366 Stimmen

Verstehen von setRetainInstance(boolean) des Fragments

Beginnen Sie mit der Dokumentation:

public void setRetainInstance (boolean retain)

Kontrollieren Sie, ob eine Fragmentinstanz bei der Neuerstellung einer Aktivität (z. B. bei einer Konfigurationsänderung) erhalten bleibt. Dies kann nur bei Fragmenten verwendet werden, die sich nicht im Backstack befinden. Wenn diese Option gesetzt ist, unterscheidet sich der Lebenszyklus des Fragments leicht, wenn eine Activity neu erstellt wird:

  • onDestroy() wird nicht aufgerufen (aber onDetach() wird trotzdem aufgerufen, da das Fragment von seiner aktuellen Aktivität getrennt wird).
  • onCreate(Bundle) wird nicht aufgerufen, da das Fragment nicht neu erstellt wird.
  • onAttach(Activity) und onActivityCreated(Bundle) werden weiterhin aufgerufen.

Ich habe einige Fragen:

  • Behält das Fragment auch seine Ansicht bei, oder wird diese bei einer Konfigurationsänderung 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 hinteren Stapel?

  • In welchen Anwendungsfällen ist es sinnvoll, diese Methode einzusetzen?

367voto

Alex Lockwood Punkte 82384

Zuallererst sollten Sie sich meine Stelle über erhaltene Fragmente. Das könnte helfen.

Um nun Ihre Fragen zu beantworten:

Behält das Fragment auch seine siehe Status, oder wird dieser bei einer Konfigurationsänderung neu erstellt - was genau wird "beibehalten"?

Ja, die Fragment Der Status von "S" wird bei der Konfigurationsänderung beibehalten. Konkret bedeutet "beibehalten", dass das Fragment no bei Konfigurationsänderungen zerstört werden. Das heißt, die Fragment wird beibehalten selbst wenn die Konfigurationsänderung die zugrunde liegende Activity zerstört werden.

Wird das Fragment zerstört, wenn der Benutzer die Aktivität verlässt?

Genau wie Activity s, Fragment s können vom System zerstört werden, wenn die Speicherressourcen knapp sind. Ob Sie Ihre Fragmente ihren Instanzstatus über Konfigurationsänderungen hinweg beibehalten lassen, hat keinen Einfluss darauf, ob das System die Fragmente zerstört oder nicht. Fragment s, sobald Sie die Activity . Wenn Sie die Activity (z. B. durch Drücken der Home-Taste), wird die Fragment s zerstört werden können oder nicht. Wenn Sie die Activity indem Sie die Zurück-Taste drücken (und damit die finish() und die effektive Zerstörung der Activity ), alle der Activity s beigefügt Fragment s werden ebenfalls zerstört.

Warum funktioniert es nicht mit Fragmenten auf dem hinteren Stapel?

Es gibt wahrscheinlich mehrere Gründe, warum es nicht unterstützt wird, aber der offensichtlichste Grund ist, dass die Activity enthält einen Verweis auf den FragmentManager und die FragmentManager verwaltet den Backstack. Das heißt, unabhängig davon, ob Sie sich dafür entscheiden, Ihre Fragment s oder nicht, die Activity (und damit die FragmentManager 's backstack) wird bei einer Konfigurationsänderung zerstört. Ein weiterer Grund, warum es nicht funktionieren könnte, ist, dass die Dinge kompliziert werden könnten, wenn beide erhaltenen Fragmente y nicht zurückgehaltene Fragmente durften auf demselben Backstack existieren.

In welchen Anwendungsfällen ist es sinnvoll, diese Methode einzusetzen?

Zurückgehaltene Fragmente können für die Weitergabe von Zustandsinformationen - insbesondere für das Thread-Management - über Aktivitätsinstanzen hinweg sehr nützlich sein. Zum Beispiel kann ein Fragment als Host für eine Instanz von Thread ou AsyncTask und verwaltet seinen Betrieb. Siehe mein Blogbeitrag zu diesem Thema für weitere Informationen.

Im Allgemeinen würde ich es ähnlich behandeln wie die Verwendung von onConfigurationChanged mit einer Activity ... verwenden Sie es nicht als Hilfsmittel, nur weil Sie zu faul sind, eine Orientierungsänderung richtig umzusetzen/zu handhaben. Verwenden Sie es nur, wenn Sie es brauchen.

28voto

suitianshi Punkte 3270

setRetaininstance ist nur nützlich, wenn Ihr activity zerstört und aufgrund einer Konfigurationsänderung neu erstellt wird, da die Instanzen während eines Aufrufs von onRetainNonConfigurationInstance . Das heißt, wenn Sie das Gerät drehen, bleiben die erhaltenen Fragmente erhalten (sie werden nicht zerstört und neu erstellt), aber wenn die Laufzeit die Aktivität beendet, um Ressourcen zurückzugewinnen, ist nichts mehr übrig. Wenn Sie die Zurück-Taste drücken und die Aktivität beenden, wird alles zerstört.

Sagen wir, ich habe eine Reihe von Bitmaps vom Server heruntergeladen und jede ist 1MB groß, wenn der Benutzer versehentlich sein Gerät dreht, möchte ich sicherlich nicht die ganze Arbeit des Herunterladens noch einmal machen, also erstelle ich eine Fragment mit meinen Bitmaps und fügen sie dem Manager hinzu und rufen setRetainInstance Alle Bitmaps bleiben erhalten, auch wenn sich die Ausrichtung des Bildschirms ändert.

13voto

Kejun Xia Punkte 177

SetRetainInstance(true) lässt das Fragment sozusagen überleben. Seine Mitglieder werden bei Konfigurationsänderungen wie Rotation beibehalten. Es kann aber dennoch beendet werden, wenn die Aktivität im Hintergrund beendet wird. Wenn die enthaltende Aktivität im Hintergrund vom System beendet wird, sollte ihr instanceState vom System gespeichert werden, das Sie onSaveInstanceState richtig behandelt haben. Mit anderen Worten: onSaveInstanceState wird immer aufgerufen. Obwohl onCreateView nicht aufgerufen wird, wenn SetRetainInstance wahr ist und das Fragment/die Aktivität noch nicht beendet wurde, wird es dennoch aufgerufen, wenn es beendet wurde und versucht wird, zurückgebracht zu werden.

Hier sind einige Analysen der Android-Aktivitäten/Fragmente, die hoffentlich hilfreich sind. http://ideaventure.blogspot.com.au/2014/01/Android-activityfragment-life-cycle.html

13voto

Gastón Saillén Punkte 10484

SetRetainInstance() - Veraltet

Als Fragmente Version 1.3.0-alpha01

Die Methode setRetainInstance() für Fragmente ist veraltet. Mit der Einführung von ViewModels, haben Entwickler eine spezifische API für Beibehaltung von Zuständen, die mit Activities, Fragmenten und Navigationsgraphen. Dies erlaubt es Entwicklern eine normale, nicht Fragment zu verwenden und den spezifischen Zustand, den sie beibehalten getrennt zu halten und so eine häufige Quelle von Lecks zu vermeiden, während die nützlichen Eigenschaften einer einzigen Erstellung und Zerstörung des gespeicherten Zustandes (nämlich der Konstruktor des ViewModels und der onCleared() Callback den es erhält).

2voto

Marian Paździoch Punkte 8170

setRetainInstance(boolean) ist nützlich, wenn Sie eine Komponente haben möchten, die nicht an den Lebenszyklus einer Aktivität gebunden ist. Diese Technik wird zum Beispiel verwendet von rxloader Android's activity lifecyle für rxjava's Observable zu handhaben" (was ich gefunden habe aquí ).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X