Lifecycle in Jetpack Compose   Teil von Android Jetpack.

Lebenszyklusbewusste Komponenten führen Aktionen als Reaktion auf eine Änderung des Lebenszyklusstatus der Host-Aktivität aus. Das androidx.lifecycle.compose-Artefakt bietet spezielle APIs, die Ressourcen automatisch bereinigen, wenn sie den Bildschirm verlassen oder die Anwendung in den Hintergrund wechselt.

Zu den wichtigsten APIs gehören:

Diese Integrationen bieten praktische Hooks zum Verwalten von Lebenszyklen in der Compose-Hierarchie. In diesem Dokument wird beschrieben, wie Sie sie in Ihrer App verwenden können.

Lebenszyklusstatus mit Abläufen erfassen

Lifecycle stellt eine currentStateFlow-Eigenschaft bereit, die den aktuellen Lifecycle.State als Kotlin-StateFlow enthält. Sie können Flow als State erfassen. So kann Ihre App Änderungen im Lebenszyklus während der Komposition lesen.

val lifecycleOwner = LocalLifecycleOwner.current
val stateFlow = lifecycleOwner.lifecycle.currentStateFlow

val currentLifecycleState by stateFlow.collectAsState()

Das vorherige Beispiel ist über das lifecycle-common-Modul zugänglich. Die Methode currentStateAsState() ist im Modul lifecycle-runtime-compose verfügbar. Damit können Sie den aktuellen Lifecycle-Status bequem mit einer einzigen Zeile lesen. Das folgende Beispiel veranschaulicht dies:

val lifecycleOwner = LocalLifecycleOwner.current
val currentLifecycleState = lifecycleOwner.lifecycle.currentStateAsState()

Code bei Lebenszyklusereignissen ausführen

Anstatt eine separate Klasse zu erstellen, die DefaultLifecycleObserver implementiert, und sie manuell zum Lebenszyklus hinzuzufügen, können Sie die Lebenszykluslogik inline mit bestimmten Effekten deklarieren. Mit LifecycleEffects können Sie einen Block ausführen, wenn ein bestimmtes Lifecycle.Event direkt in der Komposition auftritt.

LifecycleEventEffect

Verwenden Sie LifecycleEventEffect, um einen Codeblock auszuführen, wenn ein bestimmtes Ereignis eintritt. Das ist am besten für einmalige Ereignisse wie Protokollierung oder Analyse geeignet, bei denen weder ein Erfolg noch ein sofortiges Ergebnis erforderlich ist.

@Composable
fun AnalyticsTracker(screenName: String) {
    // Log an event when the app receives ON_RESUME (e.g. comes to foreground)
    LifecycleEventEffect(Lifecycle.Event.ON_RESUME) {
        Analytics.logView(screenName)
    }
}

LifecycleStartEffect

Verwenden Sie für gekoppelte Start-/Stoppvorgänge, die ausgeführt werden müssen, während die App gestartet (sichtbar) ist, und die bereinigt werden müssen, wenn die App gestoppt (im Hintergrund) wird, LifecycleStartEffect.

Ähnlich wie bei anderen Compose-Effekten (z. B. LaunchedEffect) werden bei LifecycleStartEffect Tasten akzeptiert. Wenn sich der Schlüssel ändert, wird der Block noch einmal ausgeführt.

Wenn ein Lifecycle.Event.ON_STOP-Ereignis eintritt oder der Effekt die Komposition verlässt, wird der onStopOrDispose-Block ausgeführt, um alle Arbeiten zu bereinigen, die Teil des Startblocks waren.

@Composable
fun LocationMonitor(locationManager: LocationManager) {
    // Starts monitoring when ON_START is dispatched
    // Stops monitoring when ON_STOP is dispatched
    //   (or the composable leaves the screen)
    LifecycleStartEffect(locationManager) {
        val listener = LocationListener { location ->
            /* update UI */
        }
        locationManager.requestLocationUpdates(listener)
        // The cleanup block automatically runs on ON_STOP or on disposal
        onStopOrDispose {
            locationManager.removeUpdates(listener)
        }
    }
}

Informationen zu anderen Arten von Nebeneffekten finden Sie unter Nebeneffekte in Compose.

LifecycleResumeEffect

LifecycleResumeEffect funktioniert genauso wie LifecycleStartEffect, ist aber stattdessen an das Ereignis Lifecycle.Event.ON_RESUME gebunden. Außerdem wird ein onPauseOrDispose-Block bereitgestellt, der die Bereinigung durchführt, wenn ON_PAUSE gesendet wird oder die komponierbare Funktion vom Bildschirm verschwindet.

Diese API ist nützlich für Ressourcen, die nur aktiv sein müssen, wenn der Nutzer mit der App interagiert, z. B. Kameras oder Animationen.

@Composable
fun CameraPreview(cameraController: CameraController) {
    LifecycleResumeEffect(cameraController) {
        cameraController.startPreview()

        onPauseOrDispose {
            cameraController.stopPreview()
        }
    }
}

Auf LifecycleOwner zugreifen

In Compose ist die LifecycleOwner implizit über die CompositionLocal mit dem Namen LocalLifecycleOwner verfügbar. Standardmäßig wird dieser Rechteinhaber vom Stamm-Host Ihrer Kompositionshierarchie bereitgestellt.

val lifecycleOwner = LocalLifecycleOwner.current

Bei vielen Apps reicht es aus, diesen Standardinhaber zu prüfen oder an lebenszyklusbewusste Effekte zu übergeben. Bei benutzerdefinierter Navigation oder komplexen Layouts sollten Sie jedoch möglicherweise eigene LifecycleOwner erstellen, um Lebenszyklusstatus auf bestimmte Abschnitte der Benutzeroberfläche zu beschränken. Navigationsbibliotheken wie Navigation 3 erledigen dies automatisch, sodass jeder Bildschirm seinen eigenen Lebenszyklus hat.

Benutzerdefinierten LifecycleOwner erstellen

Mit der rememberLifecycleOwner() API können Sie eine benutzerdefinierte LifecycleOwner erstellen und speichern. Das ist besonders nützlich für Komponenten wie HorizontalPager, bei denen nur die sichtbare, gerenderte Seite RESUMED sein soll, während für die angrenzenden, nicht sichtbaren Seiten ein maxState von STARTED festgelegt wird.

val pagerState = rememberPagerState(pageCount = { 10 })

HorizontalPager(state = pagerState) { pageNum ->
    val pageLifecycleOwner = rememberLifecycleOwner(
        maxState = if (pagerState.settledPage == pageNum) {
            Lifecycle.State.RESUMED
        } else {
            Lifecycle.State.STARTED
        }
    )

    CompositionLocalProvider(LocalLifecycleOwner provides pageLifecycleOwner) {
        // Your pages here. Their lifecycle-aware components respect the
        // custom maxState defined above.
    }
}

Weitere Informationen zu CompositionLocal finden Sie unter Lokal begrenzte Daten mit CompositionLocal.

Best Practices für lebenszyklusbewusste Komponenten

  • Halten Sie Ihre UI-Controller so schlank wie möglich. Sie sollten nicht versuchen, eigene Daten abzurufen, sondern dazu ein ViewModel verwenden und ein StateFlow-Objekt beobachten, um die Änderungen in der Benutzeroberfläche zu übernehmen.
  • Versuchen Sie, datengesteuerte UIs zu erstellen, bei denen der UI-Controller dafür verantwortlich ist, die UI zu aktualisieren, wenn sich Daten ändern, oder Nutzeraktionen an die ViewModel zu senden.
  • Platzieren Sie Ihre Datenlogik in der Klasse ViewModel. ViewModel sollte als Verbindung zwischen Ihrem UI-Controller und dem Rest Ihrer App dienen. Es ist jedoch nicht die Aufgabe von ViewModel, Daten abzurufen (z. B. aus einem Netzwerk). Stattdessen sollte ViewModel die entsprechende Komponente aufrufen, um die Daten abzurufen, und das Ergebnis dann an den UI-Controller zurückgeben.
  • Verwenden Sie Kotlin-Coroutinen, um lang andauernde Aufgaben und andere Vorgänge zu verwalten, die asynchron ausgeführt werden können.
  • Die Start-/Stopplogik sollte sich in der Composable befinden, die sie tatsächlich benötigt. So wird die Logik automatisch entfernt, wenn das entsprechende UI-Element vom Bildschirm entfernt wird (z. B. in einem Navigationsdiagramm oder wenn die Sichtbarkeit bedingt ist).
  • collectAsStateWithLifecycle für Daten verwenden Starten oder beenden Sie die Erfassung von Flow nicht manuell basierend auf Lifecycle-Ereignissen. Verwenden Sie stattdessen collectAsStateWithLifecycle, um Streams effizient in den UI-Status zu konvertieren. Dadurch werden Akku und Ressourcen geschont, da Flow pausiert werden, wenn die App im Hintergrund ausgeführt wird.

Weitere Informationen zu Flow finden Sie unter Andere unterstützte Statusarten.

Anwendungsfälle für lebenszyklusbewusste Komponenten

Lebenszyklusbewusste Komponenten können die Verwaltung von Lebenszyklen in verschiedenen Fällen erheblich erleichtern. Hier einige Beispiele:

  • Zwischen groben und detaillierten Standortaktualisierungen wechseln. Mit LifecycleStartEffect können Sie detaillierte Standortupdates aktivieren, während Ihre App sichtbar ist (ON_START). Außerdem können Sie den Listener automatisch bereinigen oder zu ungenauen Updates wechseln, wenn die App im Hintergrund ausgeführt wird (ON_STOP).
  • Video-Buffering anhalten und starten. Verwenden Sie LifecycleResumeEffect, um die eigentliche Videowiedergabe aufzuschieben, bis die App vollständig im Vordergrund und interaktiv ist (ON_RESUME). Außerdem können Sie damit dafür sorgen, dass die Wiedergabe pausiert und Ressourcen freigegeben werden, wenn die App in den Hintergrund verschoben wird (ON_PAUSE).
  • Netzwerkstreaming starten und beenden Mit collectAsStateWithLifecycle können Sie kontinuierliche Datenstreams beobachten, z. B. einen Kotlin-Flow von einem Netzwerk-Socket. So erhalten Sie Live-Updates, während sich eine App im Vordergrund befindet. Die Erfassung wird automatisch beendet, wenn die App in den Hintergrund wechselt.
  • Aufwendige Aufgaben pausieren und fortsetzen Verwenden Sie LifecycleResumeEffect, um das Anhalten von aufwendigen visuellen Updates zu verarbeiten, wenn die App im Hintergrund ausgeführt wird, und sie fortzusetzen, wenn die App im Vordergrund ausgeführt wird.

ON_STOP-Ereignisse sicher verarbeiten

Compose ist so konzipiert, dass ON_STOP-Ereignisse sicher verarbeitet werden.

  • Status ist sicher:Sie können MutableState (z. B. mit uiState.value = ...) jederzeit aktualisieren, auch wenn die App im Hintergrund ausgeführt wird. Compose wartet, bis die App sichtbar ist, um die Änderungen zu rendern.
  • Automatische Bereinigung:Bei Effekten wie LifecycleStartEffect wird der Bereinigungsblock (onStopOrDispose) genau dann ausgeführt, wenn der Lebenszyklus zu STOPPED wechselt. So wird verhindert, dass Sie schwere Ressourcen (z. B. Kamera oder Standort) belegen, während die App im Hintergrund ausgeführt wird.

Weitere Informationen zu MutableState finden Sie unter Zustand und Jetpack Compose.

Zusätzliche Ressourcen

Weitere Informationen zum Umgang mit Lebenszyklen mit lebenszyklusbewussten Komponenten finden Sie in den folgenden zusätzlichen Ressourcen.

Inhalte ansehen