Status wird mit Fragmenten gespeichert

Verschiedene Android-Systemvorgänge können den Status des Fragments beeinflussen. Damit der Status des Nutzers gespeichert wird, speichert und stellt das Android-Framework die Fragmente und den Back-Stack automatisch wieder her. Daher müssen alle Daten in Ihrem Fragment ebenfalls gespeichert und wiederhergestellt werden.

In der folgenden Tabelle sind die Vorgänge aufgeführt, die dazu führen, dass Ihr Fragment den Status verliert. Außerdem wird erläutert, ob die verschiedenen Statustypen durch diese Änderungen bestehen bleiben. In der Tabelle werden folgende Bundesstaatentypen aufgeführt:

  • Variablen: lokale Variablen im Fragment
  • Ansichtsstatus: alle Daten, die einer oder mehreren Datenansichten im Fragment gehören
  • SavedState: Daten, die dieser Fragmentinstanz gehören und in onSaveInstanceState() gespeichert werden sollen
  • NonConfig: Daten, die aus einer externen Quelle wie einem Server oder einem lokalen Repository abgerufen werden, oder vom Nutzer erstellte Daten, die nach dem Commit an einen Server gesendet werden.

Häufig werden Variables wie SavedState behandelt. In der folgenden Tabelle wird jedoch zwischen den beiden Variablen unterschieden, um die Auswirkungen der verschiedenen Vorgänge auf sie zu demonstrieren.

Betrieb Variablen Status anzeigen Gespeicherter Status Keine Konfiguration
Dem Back-Stack hinzugefügt x
Konfigurationsänderung x
Prozesstod/Erholung x ✓*
Entfernt, nicht in den Back-Stack aufgenommen x x x x
Organisator abgeschlossen x x x x

* Der Status „Nicht konfiguriert“ kann mit dem Modul „Gespeicherter Status“ für ViewModel nach dem Prozessende beibehalten werden.

Tabelle 1:Verschiedene Fragment-Destruktionsvorgänge und ihre Auswirkungen auf verschiedene Statustypen.

Sehen wir uns ein konkretes Beispiel an. Angenommen, ein Bildschirm generiert einen zufälligen String, der in einem TextView-Element angezeigt wird und eine Option zum Bearbeiten des Strings bietet, bevor Sie ihn an einen Freund senden:

Zufallstextgenerator, der verschiedene Statustypen zeigt
Abbildung 1: Zufallstextgenerator-App, die verschiedene Statustypen veranschaulicht

Wenn der Nutzer in diesem Beispiel auf die Schaltfläche „Bearbeiten“ klickt, wird in der Anwendung eine EditText-Ansicht angezeigt, in der der Nutzer die Mitteilung 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 kann es erforderlich sein, vier Daten zu verwalten, um ein nahtloses Erlebnis zu gewährleisten:

Daten Typ Statustyp Beschreibung
seed Long Keine Konfiguration Seed, der zur zufälligen Generierung einer neuen guten Tat verwendet wird. Wird beim Erstellen von ViewModel generiert.
randomGoodDeed String SavedState + Variable Wird generiert, wenn das Fragment zum ersten Mal erstellt wird. randomGoodDeed wird gespeichert, damit Nutzer auch nach dem Tod und der Neuerstellung des Prozesses die gleiche gute Tat sehen.
isEditing Boolean SavedState + Variable Das boolesche Flag wird auf true gesetzt, 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 aufrufen (Inhaber ist EditText) Der bearbeitete Text in der Ansicht EditText. In der Ansicht EditText wird dieser Text gespeichert, damit laufende Änderungen des Nutzers nicht verloren gehen.

Tabelle 2:Besagt, dass die Zufallstextgenerator-App verwaltet werden muss.

In den folgenden Abschnitten wird beschrieben, wie Sie den Status Ihrer Daten mithilfe destruktiver Vorgänge ordnungsgemäß verwalten.

Status anzeigen

Datenansichten sind für die Verwaltung ihres eigenen Status verantwortlich. Wenn eine Ansicht beispielsweise Nutzereingaben akzeptiert, liegt es in der Verantwortung der Ansicht, diese Eingabe zu speichern und wiederherzustellen, um Konfigurationsänderungen zu verarbeiten. Alle Ansichten, die vom Android-Framework bereitgestellt werden, haben eine eigene Implementierung von onSaveInstanceState() und onRestoreInstanceState(), sodass Sie den Ansichtsstatus nicht innerhalb des Fragments verwalten müssen.

Im vorherigen Szenario wird der bearbeitete String beispielsweise in einem EditText enthalten. Ein EditText kennt den Wert des angezeigten Textes sowie andere Details wie den Anfang und das Ende des ausgewählten Textes.

Eine Ansicht benötigt eine ID, um ihren Status beizubehalten. Diese ID muss innerhalb des Fragments und seiner Ansichtshierarchie eindeutig sein. Ansichten ohne ID können ihren Status nicht beibehalten.

<EditText
    android:id="@+id/good_deed_edit_text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

Wie in Tabelle 1 erwähnt, werden die ViewState in Ansichten über alle Vorgänge gespeichert und wiederhergestellt, die das Fragment nicht entfernen oder den Host zerstören.

SavedState

Das Fragment ist für die Verwaltung kleiner Mengen dynamischer Status verantwortlich, die für die Funktionsweise des Fragments wesentlich sind. Mit Fragment.onSaveInstanceState(Bundle) können Sie einfach virtualisierte Daten beibehalten. Ähnlich wie bei Activity.onSaveInstanceState(Bundle) werden die Daten, die Sie in das Bundle aufnehmen, durch Konfigurationsänderungen sowie durch Tod und Wiederherstellung beibehalten und stehen in den Methoden onCreate(Bundle), onCreateView(LayoutInflater, ViewGroup, Bundle) und onViewCreated(View, Bundle) Ihres Fragments zur Verfügung.

In Fortführung des vorherigen Beispiels ist randomGoodDeed die dem Nutzer angezeigte Urkunde und isEditing ein Flag, mit dem bestimmt wird, ob das Fragment EditText ein- oder ausblendet. 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. Da sie als gespeichert behandelt werden, bleiben sie bei allen destruktiven Vorgängen erhalten.

Keine Konfiguration

Nicht-Konfigurationsdaten sollten außerhalb des Fragments platziert werden, beispielsweise in einem ViewModel. Im vorherigen Beispiel oben wird seed (unser Nichtkonfigurationsstatus) im ViewModel generiert. Die Logik zur Beibehaltung des Status gehört der 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;
    }
}

Die Klasse ViewModel lässt standardmäßig Konfigurationsänderungen wie Bildschirmrotationen zu, und bleibt im Speicher, wenn das Fragment auf dem Back-Stack platziert wird. Nach dem Beenden und Wiederherstellen des Prozesses wird die ViewModel neu erstellt und eine neue seed generiert. Wenn Sie ein SavedState-Modul zu ViewModel hinzufügen, kann das ViewModel den einfachen Zustand durch Löschen und Wiederherstellen von Prozessen beibehalten.

Weitere Informationen

Weitere Informationen zum Verwalten des Fragmentstatus finden Sie in den folgenden zusätzlichen Ressourcen.

Codelabs

Leitfäden