Dies ist tatsächlich bemerkenswert kompliziert; Die kurze Antwort bezüglich der noch lebenden Aktivität ist Ja und Nein. Wenn Sie die Ressourcen für Ihre Activity
korrekt bereinigt haben, wird Ihre Aktivität (eventuell) vom Garbage Collector bereinigt.
In Bezug auf die Bereinigung ist es wichtig zu wissen, dass Xamarin discourages (slide 44 onwards) Finalizer verwenden. Hier ist der Grund:
- Sie sind nicht innerhalb einer Frist laufen garantiert.
- Sie laufen nicht in einer bestimmten Reihenfolge.
- Sie machen Objekte länger leben.
- Der GC weiß nicht über nicht verwaltete Ressourcen.
daher einen Finalizer mit Bereinigung durchzuführen, ist der falsche Weg, Dinge zu tun ... Wenn Sie sicherstellen möchten, dass MainActivity
zerstört wird, manuell den Activity
entsorgen es OnDestroy
Rückruf ist:
protected override void OnDestroy()
{
base.OnDestroy();
this.Dispose(); // Sever java binding.
}
Dadurch wird Mono die Verbindung peer object unterbrechen und die Aktivität während des nächsten Speicherbereinigungszyklus (GC.Collect(GC.MaxGeneration)
) zerstören. Aus der Dokumentation:
Um die Lebensdauer des Objekts zu verkürzen, sollte Java.Lang.Object.Dispose() aufgerufen werden. Dies wird die Verbindung auf dem Objekt zwischen den beiden VMs manuell "trennen", indem die globale Referenz freigegeben wird, wodurch die Objekte schneller gesammelt werden können.
Hinweis gibt den Abrufauftrag, this.Dispose()
mussnach aufgerufen wird jeder Code, der wieder in Android Land aufruft. Warum? Alle Verbindungen zwischen Java und .NET sind nun unterbrochen, um es Android zu ermöglichen, Ressourcen zurückzugewinnen, so dass jeder Code, der Android-Land-Objekte (Fragment, Aktivität, Adapter) verwendet, fehlschlägt.
Nun zu einigen Debugging-Techniken für Aktivität Lecks. Um sicherzustellen, dass Ihre Aktivität gereinigt wird, fügen Sie den folgenden Code in die OnCreate
Methode Ihrer Apps Eintrag Activity
:
var vmPolicy = new StrictMode.VmPolicy.Builder();
StrictMode.SetVmPolicy (vmPolicy.DetectActivityLeaks().PenaltyLog().Build());
Dies ermöglicht StrictMode
, ein nützliches Debugging-Tool, das informiert Sie gerne, wenn Sie Ressourcen geleckt haben. Wenn einer Ihrer Apps Aktivitäten nicht korrekt freigegeben, wird es so etwas wie dies in den Ausgabestream Dump:
[StrictMode] class activitydispose.LeakyActivity; instances=2; limit=1
[StrictMode] android.os.StrictMode$InstanceCountViolation: class activitydispose.LeakyActivity; instances=2; limit=1
[StrictMode] at android.os.StrictMode.setClassInstanceLimit(StrictMode.java:1)
In Kombination mit dem Dispose()
Anruf, können Sie prüfen, ob Tätigkeiten freigegeben werden. Hier ist, wie Sie normalerweise eine Activity
und ihre Ressourcen in Xamarin.Android:
protected override void Dispose (bool disposing)
{
// TODO: Dispose logic here.
base.Dispose (disposing);
GC.Collect(GC.MaxGeneration); // Will force cleanup but not recommended.
}
protected override void OnDestroy()
{
if (density != null) { // Release Java objects (buttons, adapters etc) here
density.Dispose();
density = null;
}
base.OnDestroy();
this.Dispose(); // Sever java binding.
}
"Das ist eigentlich bemerkenswert kompliziert" <------ jede Antwort, die damit beginnt, wird eine gute sein. – rarrarrarrr
Diese Info ist sehr nützlich. StrictMode rockt – xleon