Retained Fragments mit UI- und Speicherlecks
Ich habe gelesen, dass die Einstellung .setOnRetainInstance(true)
auf Fragmente präsentiert UI führen kann zu memory-leaks.
Könnte jemand bitte erklären, wie und warum das passieren würde? Ich habe nicht eine ausführliche Erklärung irgendwo.
InformationsquelleAutor der Frage Zsombor Erdődy-Nagy | 2012-11-16
Du musst angemeldet sein, um einen Kommentar abzugeben.
In einem
Fragment
mit UI-Sie sparen Häufig einigeView
s als Instanz Staat zu beschleunigen den Zugriff. Zum Beispiel einen link zu IhrerEditText
so dass Sie nicht haben, umfindViewById
es die ganze Zeit.Das problem ist, dass
View
hält eine Referenz auf dieActivity
Kontext. Nun, wenn Sie halten eineView
Sie auch behalten eine Referenz auf diesen Kontext.Ist kein problem, wenn der Kontext ist immer noch gültig, aber der typische Fall behalten, ist ein Neustart der Aktivität. Sehr oft ist für eine Bildschirm-rotation zum Beispiel. Aktivität Erholung schaffen einen neuen Kontext und in alte Zusammenhänge werden sollen Müll gesammelt. Aber es kann nicht sein, Müll gesammelt, jetzt seit Ihr
Fragment
noch ein Verweis auf den alten.Folgende Beispiel zeigt, wie man es nicht machen
Loswerden, dass problem ist, müssen Sie deaktivieren Sie alle Verweise auf Ihrer Benutzeroberfläche in
onDestroyView
. Sobald dieFragment
Instanz wieder verwendet, werden Sie aufgefordert, erstellen Sie eine neue UI aufonCreateView
. Es gibt auch keine Stelle dabei, die UI nachonDestroyView
. Das Ui wird nicht verwendet.Die Fehlerbehebung in diesem Beispiel ist nur die änderung
onDestroyView
zuUnd außerdem halten Verweise auf
View
s sollten Sie natürlich nicht halten, Verweise auf dieActivity
(z.B. vononAttach
- sauber aufonDetach
) oder jedeContext
(es sei denn, es ist dieApplication
Kontext).InformationsquelleAutor der Antwort zapl
Vorsichtig sein, wenn die Beibehaltung bestimmter Objekte, die sind gekoppelt an die Aktivität.
Vorsicht:Während Sie zurückgeben kann jedes Objekt, sollten Sie niemals ein Objekt, das gebunden ist, um die Aktivität, wie ein Drawableein Adapterein Ansicht oder andere Gegenstände, die im Zusammenhang mit einem Kontext. Wenn Sie es tun, wird es undicht, der in allen Ansichten und Ressourcen der ursprünglichen Aktivität Instanz. (Undichte Ressourcen bedeutet, dass Ihre Anwendung pflegt Sie, und Sie werden nicht garbage-collected, so viel Speicher verloren gehen kann.)
http://developer.android.com/guide/topics/resources/runtime-changes.html#RetainingAnObject
InformationsquelleAutor der Antwort Emanuel Canha
setRetainInstance(true)
wird verwendet, um retain-Instanzen von dynamischen Fragmente während einer Aktivität Erholung, wie eine Bildschirm-rotation oder anderen config-änderungen. Dies bedeutet nicht, dass das Fragment beibehalten werden für immer durch das system obwohl.Wenn eine Aktivität beendet wird, aus anderen Gründen, wie der Benutzer die Beendigung der Aktivität (d.h. drücken der Taste back), das Fragment sollte für die garbage collection freigegeben.
InformationsquelleAutor der Antwort wsanville
"SetRetainInstance" wird verwendet, um den Zustand des fragments, wenn die activity neu erstellt wird.
Laut der offiziellen Dokumentation: wenn wir "setRetainInstance", 2 Methoden der fragment-Lebenszyklus, nicht ausgeführt wird (onCreate, onDestroy).
Allerdings sind die Ansichten enthalten, die in das fragment wird neu erstellt werden, und das ist, weil der Lebenszyklus ausgeführt werden, die von der "onCreateView".
In diesen Fällen, wenn wir gespeichert haben, werden einige Daten in "onSaveInstanceState", sollten wir Fragen, für die es in der "onActivityCreated" statt in die "onCreate".
Oficial info: https://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)
Mehr info: https://inthecheesefactory.com/blog/fragment-state-saving-best-practices/en
InformationsquelleAutor der Antwort FacuArg
können Sie diesen
onDestroy()
auf und ruft den garbage-collector.InformationsquelleAutor der Antwort Metro Polinet