Status wird mit Fragmenten gespeichert

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:

App zum Generieren von Zufallstext, die verschiedene Arten von Status demonstriert
Abbildung 1. Zufallstextgenerator-App, die verschiedene Statustypen demonstriert.

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.

Codelabs

Leitfäden