In den folgenden Abschnitten werden Strategien zum Speichern des Backstacks und zum Speichern des Status beschrieben, der mit Einträgen im Backstack verknüpft ist.
Backstack speichern
Für eine gute Nutzererfahrung ist es wichtig, dass der Navigationsstatus Ihrer App bei verschiedenen Lebenszyklusereignissen erhalten bleibt, einschließlich Konfigurationsänderungen und Prozessende. Bei Navigation 3 sind Sie für den Backstack verantwortlich. Es gibt also keine strengen Richtlinien dazu, wie Sie ihn erstellen oder speichern sollten. Navigation 3 bietet jedoch eine praktische Methode, mit der Sie einen speicherbaren Rückstapel erhalten: rememberNavBackStack
.
rememberNavBackStack
verwenden
Die zusammensetzbare Funktion rememberNavBackStack
dient zum Erstellen eines Backstacks, der bei Konfigurationsänderungen und Prozessende erhalten bleibt.
Damit rememberNavBackStack
ordnungsgemäß funktioniert, müssen alle Schlüssel in Ihrem Backstack bestimmte Anforderungen erfüllen:
NavKey
-Schnittstelle implementieren: Jeder Schlüssel im Backstack muss dieNavKey
-Schnittstelle implementieren. Dies dient als Markierungsschnittstelle, die der Bibliothek signalisiert, dass der Schlüssel gespeichert werden kann.@Serializable
-Anmerkung: Zusätzlich zur Implementierung vonNavKey
müssen Ihre Schlüsselklassen und ‑objekte mit der Anmerkung@Serializable
gekennzeichnet sein.
Das folgende Snippet zeigt eine korrekte Implementierung von rememberNavBackStack
:
@Serializable data object Home : NavKey @Composable fun NavBackStack() { val backStack = rememberNavBackStack(Home) }
Alternative: In einer ViewModel
speichern
Sie können den Backstack auch in einer ViewModel
speichern.
Wenn Sie bei Verwendung eines ViewModel
- oder eines anderen benutzerdefinierten Speichers Daten auch nach dem Beenden des Prozesses beibehalten möchten, müssen Sie Folgendes tun:
- Achten Sie darauf, dass Ihre Schlüssel serialisierbar sind: Genau wie bei
rememberNavBackStack
müssen Ihre Navigationsschlüssel serialisierbar sein. - Serialisierung und Deserialisierung manuell verarbeiten: Sie sind dafür verantwortlich, die serialisierte Darstellung jedes Schlüssels manuell im nichtflüchtigen Speicher zu speichern und daraus zu deserialisieren (z.B.
SharedPreferences
, eine Datenbank oder eine Datei), wenn Ihre App in den Hintergrund wechselt oder wiederhergestellt wird.
ViewModel
bis NavEntry
Sekunden
ViewModels
werden verwendet, um den UI-Status bei Konfigurationsänderungen wie Bildschirmdrehungen beizubehalten. Standardmäßig sind ViewModels
auf die nächstgelegene ViewModelStoreOwner
beschränkt, in der Regel Ihre Activity
oder Fragment
.
Möglicherweise möchten Sie jedoch eine ViewModel
auf einen bestimmten NavEntry
(d.h. einen bestimmten Bildschirm oder ein bestimmtes Ziel) im Backstack anwenden, anstatt auf die gesamte Activity
. So wird sichergestellt, dass der Zustand der ViewModel
nur so lange beibehalten wird, wie sich diese NavEntry
im Backstack befindet, und gelöscht wird, wenn die NavEntry
herausgepoppt wird.
Die Add-on-Bibliothek androidx.lifecycle:lifecycle-viewmodel-navigation3
bietet eine NavEntryDecorator
, die dies vereinfacht. Dieser Decorator stellt für jede NavEntry
eine ViewModelStoreOwner
bereit. Wenn Sie ein ViewModel
im Inhalt eines NavEntry
erstellen (z.B. mit viewModel()
in Compose), wird es automatisch auf den Schlüssel dieses NavEntry
im Backstack beschränkt. Das bedeutet, dass die ViewModel
erstellt wird, wenn die NavEntry
dem Backstack hinzugefügt wird, und gelöscht wird, wenn sie entfernt wird.
So verwenden Sie NavEntryDecorator
, um ViewModel
s auf NavEntry
s einzugrenzen:
- Fügen Sie der Datei
app/build.gradle.kts
die Abhängigkeitandroidx.lifecycle:lifecycle-viewmodel-navigation3
hinzu. - Fügen Sie beim Erstellen eines
NavDisplay
rememberSavedStateNavEntryDecorator()
der Liste derentryDecorators
hinzu. - Fügen Sie Ihrem
NavDisplay
weitere Dekorationen hinzu.
NavDisplay( entryDecorators = listOf( // Add the default decorators for managing scenes and saving state rememberSceneSetupNavEntryDecorator(), rememberSavedStateNavEntryDecorator(), // Then add the view model store decorator rememberViewModelStoreNavEntryDecorator() ), backStack = backStack, entryProvider = entryProvider { }, )