Beginnend mit der Dokumentation:
public void setRetainInstance (boolesche Aufbewahrung)
Steuern Sie, ob eine Fragmentinstanz während der Neuerstellung der Aktivität beibehalten wird (z. B. aufgrund einer Konfigurationsänderung). Dies kann nur mit Fragmenten verwendet werden, die sich nicht im Backstack befinden. Wenn festgelegt, unterscheidet sich der Fragmentlebenszyklus geringfügig, wenn eine Aktivität neu erstellt wird:
- onDestroy () wird nicht aufgerufen (onDetach () jedoch weiterhin, da das Fragment von seiner aktuellen Aktivität getrennt wird).
- onCreate (Bundle) wird nicht aufgerufen, da das Fragment nicht neu erstellt wird.
- onAttach (Aktivität) und onActivityCreated (Bundle) werden weiterhin aufgerufen.
Ich habe ein paar Fragen:
Behält das Fragment auch seine Ansicht bei oder wird dies bei Konfigurationsänderungen neu erstellt? Was genau bedeutet "beibehalten"?
Wird das Fragment zerstört, wenn der Benutzer die Aktivität verlässt?
Warum funktioniert es nicht mit Fragmenten auf dem Backstack?
In welchen Anwendungsfällen ist diese Methode sinnvoll?
Antworten:
Schauen Sie sich zunächst meinen Beitrag zu aufbewahrten Fragmenten an. Es könnte helfen.
Um Ihre Fragen zu beantworten:
Ja, der
Fragment
Status wird während der Konfigurationsänderung beibehalten. Insbesondere bedeutet "beibehalten", dass das Fragment bei Konfigurationsänderungen nicht zerstört wird. Das heißt, dasFragment
wird auch dann beibehalten , wenn die Konfigurationsänderung dazu führt, dass der BasiswertActivity
zerstört wird.Genau wie
Activity
s kannFragment
s vom System zerstört werden, wenn die Speicherressourcen niedrig sind. Ob Ihre Fragmente ihren Instanzstatus über Konfigurationsänderungen hinweg beibehalten, hat keinen Einfluss darauf, ob das System dasFragment
s zerstört, sobald Sie das verlassenActivity
. Wenn Sie das verlassenActivity
(dh durch Drücken der Home-Taste), kann dasFragment
s zerstört werden oder nicht. Wenn Sie dasActivity
durch Drücken der Zurück-Taste verlassen (wodurch das aufgerufenfinish()
und effektiv zerstört wirdActivity
), werden auch alleActivity
angehängtenFragment
s zerstört.Es gibt wahrscheinlich mehrere Gründe, warum es nicht unterstützt wird, aber der offensichtlichste Grund für mich ist, dass das
Activity
einen Verweis auf das enthältFragmentManager
und dasFragmentManager
den Backstack verwaltet. Das heißt, unabhängig davon, ob Sie IhrFragment
s behalten oder nicht, wird derActivity
(und damit derFragmentManager
Backstack) bei einer Konfigurationsänderung zerstört. Ein weiterer Grund, warum es möglicherweise nicht funktioniert, ist, dass es schwierig werden könnte, wenn sowohl beibehaltene als auch nicht beibehaltene Fragmente auf demselben Backstack existieren dürfen.Behaltene Fragmente können sehr nützlich sein, um Statusinformationen - insbesondere die Thread-Verwaltung - über Aktivitätsinstanzen zu verbreiten. Beispielsweise kann ein Fragment als Host für eine Instanz von
Thread
oder zurAsyncTask
Verwaltung seines Betriebs dienen. Weitere Informationen finden Sie in meinem Blogbeitrag zu diesem Thema.Im Allgemeinen würde ich es ähnlich behandeln wie
onConfigurationChanged
mit einemActivity
... Verwenden Sie es nicht als Pflaster, nur weil Sie zu faul sind, um eine Orientierungsänderung korrekt zu implementieren / zu behandeln. Verwenden Sie es nur, wenn Sie es brauchen.quelle
setRetainInstance(true)
, werden dasFragment
Java-Objekt und sein gesamter Inhalt beim Drehen nicht zerstört, sondern die Ansicht wird neu erstellt. DasonCreatedView()
heißt nochmal. Es ist im Grunde die Art und Weise, wie esActivities
seit Android 1.0 hätte funktionieren sollen . Ich denke nicht, dass es "faul" ist, es zu benutzen, oder dass es nicht "richtig" ist. Tatsächlich kann ich nicht verstehen, warum dies nicht die Standardeinstellung ist oder warum Sie es jemals deaktivieren möchten.Fragment
s werden nur bei Konfigurationsänderungen beibehalten, bei denen die zugrunde liegende Aktivität zerstört und sofort neu erstellt werden soll. In allen anderen Fällen, in denen die Aktivität zerstört wird, werden auch die zurückgehaltenen Fragmente zerstört.setRetainInstance(true)
es verwendet wird, muss man immer noch seine eigene Persistenz (savedInstanceState
oder auf andere Weise) implementieren , um alle Szenarien verarbeiten zu können: zB "Home-Schlüssel, drehen, zurück zur App" erstellt mein Fragment mit dem Konstruktor neu Aufruf, wobei alle Statusvariablen verloren gehen. Ich habe eineAsyncTask
Variable als Mitglied. Deshalb möchte ich sie beibehalten. Wenn sie funktionieren soll, muss ich die Aufgabe stoppen, den Status speichern und fortfahren, wenn der Benutzer zurückkommt. Alles in allem ist dies nur ein schneller Weg, um bei der Rotation zu helfen, aber ansonsten im Allgemeinen nutzlos.setRetaininstance
ist nur nützlich, wenn Ihreactivity
aufgrund einer Konfigurationsänderung zerstört und neu erstellt wird, da die Instanzen während eines Aufrufs von gespeichert werdenonRetainNonConfigurationInstance
. Das heißt, wenn Sie das Gerät drehen, bleiben die beibehaltenen Fragmente dort (sie werden nicht zerstört und neu erstellt). Wenn jedoch die Laufzeit die Aktivität zum Zurückfordern von Ressourcen beendet, bleibt nichts übrig. Wenn Sie die Zurück-Taste drücken und die Aktivität beenden, wird alles zerstört.Normalerweise verwende ich diese Funktion, um die Orientierung zu ändern und die Zeit zu ändern. Ich habe eine Reihe von Bitmaps vom Server heruntergeladen und jede ist 1 MB groß. Wenn der Benutzer versehentlich sein Gerät dreht, möchte ich die gesamte Download-Arbeit auf keinen Fall erneut ausführen Ich erstelle ein
Fragment
Halten meiner Bitmaps und füge es dem Manager hinzu und rufe aufsetRetainInstance
. Alle Bitmaps sind noch vorhanden, auch wenn sich die Bildschirmausrichtung ändert.quelle
mActivity
Referenz für Sie. Ich weiß aber nicht, ob die Laufzeit in diesem Fall auch Widgets in der Fragmentinstanz löschen würde. Bitte probieren Sie es aus oder tauchen Sie in den Quellcode ein.Mit SetRetainInstance (true) kann das Fragment überleben. Seine Mitglieder bleiben bei Konfigurationsänderungen wie Rotation erhalten. Es kann jedoch trotzdem getötet werden, wenn die Aktivität im Hintergrund beendet wird. Wenn die enthaltende Aktivität im Hintergrund vom System beendet wird, sollte der Instanzstatus von dem System gespeichert werden, das Sie in SaveInstanceState ordnungsgemäß verarbeitet haben. Mit anderen Worten, der onSaveInstanceState wird immer aufgerufen. Obwohl onCreateView nicht aufgerufen wird, wenn SetRetainInstance true ist und Fragment / Aktivität noch nicht beendet ist, wird es dennoch aufgerufen, wenn es getötet wird und versucht wird, zurückgebracht zu werden.
Hier sind einige Analysen der Android-Aktivität / Fragment-Hoffnung, die es hilft. http://ideaventure.blogspot.com.au/2014/01/android-activityfragment-life-cycle.html
quelle
setRetainInstance () - Veraltet
Als Fragmente Version 1.3.0-alpha01
quelle
setRetainInstance (boolean) ist nützlich, wenn Sie eine Komponente haben möchten, die nicht an den Aktivitätslebenszyklus gebunden ist. Diese Technik wird zum Beispiel von rxloader verwendet, um "den Aktivitätslebenszyklus von Android für rxjavas Observable zu handhaben" (den ich hier gefunden habe ).
quelle