Verschiedene Android-Systemvorgänge können sich auf den Status Ihres Fragments auswirken. Damit der Status des Nutzers gespeichert wird, speichert das Android-Framework die Fragmente und den Back-Stack automatisch und stellt sie wieder her. Daher müssen Sie dafür sorgen, dass alle Daten in Ihrem Fragment ebenfalls gespeichert und wiederhergestellt werden.
In der folgenden Tabelle werden die Vorgänge beschrieben, die dazu führen, dass das Fragment seinen Status verliert, und ob die verschiedenen Statustypen durch diese Änderungen beibehalten werden. In der Tabelle werden die folgenden Statustypen aufgeführt:
- Variablen: lokale Variablen im Fragment.
- Ansichtsstatus: Alle Daten, die zu einer oder mehreren Ansichten im Fragment gehören.
- SavedState: Daten, die zu dieser Fragmentinstanz gehören und in
onSaveInstanceState()
gespeichert werden sollen. - NonConfig: Daten, die aus einer externen Quelle wie einem Server oder lokalen Repository abgerufen werden, oder vom Nutzer erstellte Daten, die nach dem Commit an einen Server gesendet werden.
Oft werden Variablen wie SavedState behandelt. In der folgenden Tabelle wird jedoch zwischen den beiden unterschieden, um die Auswirkungen der verschiedenen Vorgänge auf die einzelnen zu veranschaulichen.
Betrieb | Variablen | Status ansehen | SavedState | NonConfig |
---|---|---|---|---|
Zum Backstack hinzugefügt | ✓ | ✓ | x | ✓ |
Konfigurationsänderung | x | ✓ | ✓ | ✓ |
Prozess Tod/Freizeit | x | ✓ | ✓ | ✓* |
Entfernt, nicht zum Rückstapel hinzugefügt | x | x | x | x |
Host beendet | x | x | x | x |
* Der NonConfig-Status kann mit dem Modul „Saved State“ für das ViewModel über den Prozesstod hinaus beibehalten werden.
Tabelle 1:Verschiedene zerstörerische Fragmentierungsvorgänge und ihre Auswirkungen auf verschiedene Statustypen.
Sehen wir uns ein konkretes Beispiel an. Angenommen, Sie haben einen Bildschirm, auf dem ein zufälliger String generiert, in einem TextView
angezeigt und die Möglichkeit bietet, den String zu bearbeiten, bevor er an einen Freund gesendet wird:
Angenommen, der Nutzer drückt die Schaltfläche „Bearbeiten“ und die App zeigt eine EditText
-Ansicht an, in der er die Nachricht bearbeiten kann. Wenn der Nutzer auf ABBRECHEN klickt, sollte die Ansicht EditText
gelöscht und die Sichtbarkeit auf View.GONE
gesetzt sein. Für einen solchen Bildschirm müssen möglicherweise vier Daten verwaltet werden, um eine reibungslose Nutzung zu ermöglichen:
Daten | Eingeben | Statustyp | Beschreibung |
---|---|---|---|
seed |
Long |
NonConfig | Zufallszahlen, die zum Generieren einer neuen guten Tat verwendet werden. Wird beim Erstellen von ViewModel generiert. |
randomGoodDeed |
String |
SavedState + Variable | Wird bei der ersten Erstellung des Fragments generiert.
randomGoodDeed wird gespeichert, damit die Nutzer auch nach dem Tod eines Prozesses und nach einer Wiederherstellung die gleiche zufällige Gute sehen. |
isEditing |
Boolean |
SavedState + Variable | Boolescher Wert, der auf true gesetzt ist, wenn der Nutzer mit der Bearbeitung beginnt.
isEditing wird gespeichert, damit der Bearbeitungsbereich des Bildschirms sichtbar bleibt, wenn das Fragment neu erstellt wird. |
Bearbeiteter Text | Editable |
Status ansehen (Eigentum von EditText ) |
Der bearbeitete Text in der EditText -Ansicht.
In der EditText -Ansicht wird dieser Text gespeichert, damit die in Bearbeitung befindlichen Änderungen des Nutzers nicht verloren gehen. |
Tabelle 2:Gibt an, was die App zum Generieren von Zufallstext verwalten muss.
In den folgenden Abschnitten wird beschrieben, wie Sie den Status Ihrer Daten durch zerstörerische Vorgänge richtig verwalten.
Status ansehen
Datenansichten sind für die Verwaltung ihres eigenen Status verantwortlich. Wenn eine Ansicht beispielsweise Nutzereingaben akzeptiert, ist es ihre Aufgabe, diese Eingaben zu speichern und wiederherzustellen, um Konfigurationsänderungen zu verarbeiten. Alle vom Android-Framework bereitgestellten Ansichten haben eine eigene Implementierung von onSaveInstanceState()
und onRestoreInstanceState()
. Sie müssen den Ansichtsstatus also nicht in Ihrem Fragment verwalten.
Im vorherigen Szenario wird der bearbeitete String beispielsweise in einem EditText
gespeichert. Ein EditText
kennt den Wert des angezeigten Texts sowie andere Details wie den Anfang und das Ende des ausgewählten Texts.
Eine Datenansicht benötigt eine ID, um ihren Status beizubehalten. Diese ID muss innerhalb des Fragments und seiner Ansichtshierarchie eindeutig sein. Der Status von Datenansichten ohne ID kann nicht beibehalten werden.
<EditText android:id="@+id/good_deed_edit_text" android:layout_width="match_parent" android:layout_height="wrap_content" />
Wie in Tabelle 1 erwähnt, speichern und wiederherstellen Ansichten ihre ViewState
durch alle Vorgänge, die das Fragment nicht entfernen oder den Host zerstören.
SavedState
Das Fragment ist für die Verwaltung kleiner Mengen an dynamischem Status verantwortlich, die für die Funktionsweise des Fragments unerlässlich sind. Mit Fragment.onSaveInstanceState(Bundle)
können Sie einfach serialisierte Daten aufbewahren.
Ähnlich wie bei Activity.onSaveInstanceState(Bundle)
bleiben die Daten, die Sie in das Bundle einfügen, bei Konfigurationsänderungen, Prozessende und -neustart erhalten und sind in den Methoden onCreate(Bundle)
, onCreateView(LayoutInflater, ViewGroup, Bundle)
und onViewCreated(View, Bundle)
Ihres Fragments verfügbar.
Im vorherigen Beispiel ist randomGoodDeed
die Urkunde, die dem Nutzer angezeigt wird, und isEditing
ist ein Flag, das angibt, ob die EditText
im Fragment angezeigt oder ausgeblendet wird. Dieser gespeicherte Status sollte mit onSaveInstanceState(Bundle)
beibehalten werden, wie im folgenden Beispiel gezeigt:
Kotlin
override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putBoolean(IS_EDITING_KEY, isEditing) outState.putString(RANDOM_GOOD_DEED_KEY, randomGoodDeed) }
Java
@Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(IS_EDITING_KEY, isEditing); outState.putString(RANDOM_GOOD_DEED_KEY, randomGoodDeed); }
Wenn Sie den Status in onCreate(Bundle)
wiederherstellen möchten, rufen Sie den gespeicherten Wert aus dem Bundle ab:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) isEditing = savedInstanceState?.getBoolean(IS_EDITING_KEY, false) randomGoodDeed = savedInstanceState?.getString(RANDOM_GOOD_DEED_KEY) ?: viewModel.generateRandomGoodDeed() }
Java
@Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { isEditing = savedInstanceState.getBoolean(IS_EDITING_KEY, false); randomGoodDeed = savedInstanceState.getString(RANDOM_GOOD_DEED_KEY); } else { randomGoodDeed = viewModel.generateRandomGoodDeed(); } }
Wie in Tabelle 1 erwähnt, bleiben die Variablen erhalten, wenn das Fragment auf dem Backstack platziert wird. Wenn Sie sie als gespeicherten Status behandeln, bleiben sie bei allen zerstörerischen Vorgängen erhalten.
NonConfig
NichtConfig-Daten sollten außerhalb des Fragments platziert werden, beispielsweise in einem ViewModel
. Im vorherigen Beispiel oben wird seed
(unser NonConfig-Status) in ViewModel
generiert.
Die Logik zur Aufrechterhaltung ihres Status gehört ViewModel
.
Kotlin
public class RandomGoodDeedViewModel : ViewModel() { private val seed = ... // Generate the seed private fun generateRandomGoodDeed(): String { val goodDeed = ... // Generate a random good deed using the seed return goodDeed } }
Java
public class RandomGoodDeedViewModel extends ViewModel { private Long seed = ... // Generate the seed private String generateRandomGoodDeed() { String goodDeed = ... // Generate a random good deed using the seed return goodDeed; } }
Mit der ViewModel
-Klasse können Daten Konfigurationsänderungen wie Bildschirmdrehungen überstehen und bleiben im Arbeitsspeicher, wenn das Fragment auf dem Backstack platziert wird. Nach dem Beenden und der Neuerstellung des Prozesses wird der ViewModel
neu erstellt und eine neue seed
generiert. Wenn Sie Ihrem ViewModel
ein SavedState
-Modul hinzufügen, kann der ViewModel
den einfachen Status beibehalten, wenn der Prozess beendet und neu erstellt wird.
Weitere Informationen
Weitere Informationen zum Verwalten des Fragmentstatus finden Sie in den folgenden zusätzlichen Ressourcen.