lifecycleScope ist ein integrierter CoroutineScope aus der Bibliothek androidx.lifecycle, der an den Lebenszyklus einer Activity, eines Fragments oder eines beliebigen LifecycleOwners gebunden ist und Coroutinen automatisch abbricht, wenn die Komponente zerstört wird. Laut Google Android Developers, 2025 ermöglicht lifecycleScope das sichere Ausführen von Coroutinen in der UI-Ebene, ohne dass Code nach der Zerstörung der Activity oder des Fragments ausgeführt wird. Der Scope wird automatisch abgebrochen, wenn der LifecycleOwner in den Zustand DESTROYED übergeht.
Wichtige Erkenntnisse
lifecycleScope ist eine Erweiterungseigenschaft auf dem LifecycleOwner-Interface (Activity, Fragment, Service), die einen fertigen CoroutineScope bereitstellt, der an den vollständigen Lebenszyklus der Komponente gebunden ist. Wenn der LifecycleOwner den Zustand DESTROYED erreicht, bricht lifecycleScope automatisch alle aktiven Coroutinen ab.
// In Fragment or Activity
lifecycleScope.launch {
delay(1000)
showSnackbar("Hallo!")
}
Im Gegensatz zu viewModelScope wird lifecycleScope jedes Mal abgebrochen, wenn der LifecycleOwner zerstört wird — einschließlich Bildschirmrotation. Dies macht es ideal für Operationen, die nur leben sollten, solange ein bestimmter Bildschirm sichtbar ist.
lifecycleScope ist überall dort verfügbar, wo es einen LifecycleOwner gibt:
Der automatische Abbruchmechanismus von lifecycleScope basiert auf dem Abonnieren von Lifecycle-Ereignissen. Wenn der Lifecycle unter CREATED auf DESTROYED fällt, wird der Scope abgebrochen.
| Zustand | Beschreibung | Scope aktiv |
|---|---|---|
| CREATED | LifecycleOwner erstellt, onCreate ausgeführt | Ja |
| STARTED | LifecycleOwner sichtbar (onStart) | Ja |
| RESUMED | LifecycleOwner im Vordergrund (onResume) | Ja |
| DESTROYED | LifecycleOwner zerstört (onDestroy) | Nein (Scope abgebrochen) |
lifecycleScope wird als CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate) erstellt und innerhalb des Lifecycle gespeichert. Wenn der Lifecycle in den Zustand DESTROYED übergeht, wird scope.cancel() aufgerufen. Der Mechanismus wird über LifecycleEventObserver implementiert, der beim ersten Zugriff auf den Scope Lebenszyklus-Ereignisse abonniert.
Wenn der Bildschirm gedreht wird, wird die Activity zerstört (onDestroy) und neu erstellt. lifecycleScope wird zusammen mit der alten Activity abgebrochen, und eine neue Scope-Instanz wird für die neue Activity erstellt. Dies ist ein grundlegender Unterschied zu viewModelScope, das bei Rotation erhalten bleibt.
Die lifecycle-Bibliothek bietet mehrere Möglichkeiten, Coroutinen über lifecycleScope zu starten. Betrachten wir die Entwicklung der API von veralteten Methoden zu modernen.
Der einfachste Weg ist lifecycleScope.launch { ... }. Die Coroutine startet sofort und wird bei DESTROYED abgebrochen. Sie kann jedoch Code ausführen, selbst wenn die UI nicht sichtbar ist (z. B. im Hintergrund nach onStop). Dies ist nicht immer wünschenswert.
Diese Methoden pausierten die Ausführung der Coroutine, wenn der Lifecycle unter den angegebenen Zustand fiel, und setzten sie bei Rückkehr fort. Sie wurden jedoch in lifecycle-runtime-ktx 2.6.0 als @Deprecated markiert, weil:
repeatOnLifecycle ist die von Google empfohlene Methode zum Starten von mit dem Lebenszyklus synchronisierten Coroutinen. Sie bricht die Coroutine ab und startet sie jedes Mal neu, wenn der Lifecycle den angegebenen Zustand erreicht.
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect { state ->
updateUI(state)
}
}
}
Die an repeatOnLifecycle übergebene Coroutine startet, wenn der Lifecycle STARTED erreicht, und wird abgebrochen, wenn er unter STARTED fällt. Bei Rückkehr zu STARTED wird die Coroutine von Grund auf neu gestartet. Dies ist sicher und effizient — keine Coroutinen bleiben pausiert.
Zum Sammeln von Daten aus Flow mit Lebenszyklusbewusstsein gibt es den Operator flowWithLifecycle. Er stoppt und setzt die Sammlung automatisch fort, wenn sich der Lifecycle-Zustand ändert:
viewModel.uiState
.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
.onEach { state -> updateUI(state) }
.launchIn(lifecycleScope)
Der Operator flowWithLifecycle ist die prägnanteste Möglichkeit, einen Flow in der UI-Ebene sicher zu abonnieren.
Betrachten wir drei reale Szenarien für die Verwendung von lifecycleScope in einer Android-Anwendung mit Kotlin.
class MapFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
locationProvider.observeLocation().collect { loc ->
updateMapMarker(loc)
}
}
}
}
}
Die Coroutine startet, wenn das Fragment sichtbar wird (STARTED), und wird abgebrochen, wenn es den Bildschirm verlässt (STOPPED). Wenn der Benutzer zu einer anderen App wechselt, verbrauchen Standortaktualisierungen keinen Akku.
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.RESUMED) {
animateFadeIn(titleView)
delay(200)
animateSlideUp(contentView)
}
}
Die Animation läuft nur, wenn das Fragment im Vordergrund ist (RESUMED). Wenn der Benutzer die App während der Animation minimiert, wird die Coroutine abgebrochen, und bei Rückkehr startet die Animation neu.
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
while (isActive) {
syncData()
delay(30_000L)
}
}
}
Daten werden alle 30 Sekunden synchronisiert, aber nur wenn der Bildschirm sichtbar ist. isActive prüft, ob die Coroutine abgebrochen wurde, und bietet einen sicheren Ausweg aus der Schleife beim Verlassen des Bildschirms.
Beide Scopes sind an den Lebenszyklus gebunden, jedoch an unterschiedliche Aspekte. Das Verständnis des Unterschieds ist entscheidend für eine korrekte Android-Anwendungsarchitektur.
viewModelScope ist an das ViewModel gebunden, das eine Bildschirmrotation überlebt. lifecycleScope ist an den LifecycleOwner (Activity/Fragment) gebunden, der bei Rotation zerstört und neu erstellt wird. Dies bestimmt die Anwendungsszenarien.
In der Praxis ist eine Kombination beider Scopes üblich: viewModelScope lädt Daten und verwaltet den Zustand, während lifecycleScope den Flow aus dem ViewModel mit Lebenszyklusbewusstsein abonniert. Diese Trennung der Verantwortlichkeiten gilt in der modernen Android-Entwicklung als Best Practice.
Betrachten wir vier der häufigsten Fehler, die Entwickler bei der Verwendung von lifecycleScope machen.
Wenn Sie das Laden von Daten in lifecycleScope.launch starten, wird die Coroutine bei Bildschirmrotation abgebrochen, und die Daten müssen erneut geladen werden. Verwenden Sie viewModelScope für langlebige Operationen. lifecycleScope ist nur für UI-gebundene Aufgaben.
Der direkte Aufruf von viewModel.someFlow.collect { ... } innerhalb von lifecycleScope.launch sammelt weiterhin Daten, auch wenn der Bildschirm nicht sichtbar ist. Dies kann zu UI-Updates im Hintergrund und unnötigem Overhead führen. Verwenden Sie immer repeatOnLifecycle oder flowWithLifecycle.
Obwohl lifecycleScope bei DESTROYED abgebrochen wird, kann Code nach einem Suspend-Punkt bei plötzlichem Abbruch möglicherweise nicht ausgeführt werden. Verlassen Sie sich nicht auf die Ausführung von Post-Code nach einem Suspend-Aufruf, es sei denn, Sie verwenden NonCancellable.
launchWhenStarted und seine Gegenstücke brechen die Coroutine nicht ab, sondern pausieren sie nur. Wenn der Bildschirm mehrmals zwischen Vorder- und Hintergrund wechselt, sammelt die Coroutine verschobene Aufrufe an. Wechseln Sie zu repeatOnLifecycle — dies ist der einzig korrekte Weg, um mit dem Lifecycle zu synchronisieren.
Häufig gestellte Fragen
lifecycleScope wird automatisch abgebrochen, wenn der LifecycleOwner zerstört wird. GlobalScope lebt während der gesamten Anwendungsdauer. Eine Coroutine in lifecycleScope kann die UI nach der Zerstörung der Komponente nicht aktualisieren, in GlobalScope hingegen schon, was zu Abstürzen führt. Verwenden Sie in der UI-Ebene immer lifecycleScope.
Nein, ViewModel ist kein LifecycleOwner, daher ist lifecycleScope dort nicht verfügbar. ViewModel verwendet viewModelScope. Wenn der Code in beiden Kontexten ausgeführt werden soll, extrahieren Sie die Logik in einen Use Case oder ein Repository mit Suspend-Funktionen.
Jeder Aufruf von repeatOnLifecycle erstellt eine neue Coroutine, die den Block ausführt, wenn der angegebene Lifecycle-Zustand erreicht wird. Wenn repeatOnLifecycle zweimal für denselben Zustand aufgerufen wird, werden beide Blöcke unabhängig voneinander ausgeführt. Normalerweise reicht ein Aufruf in onViewCreated aus.
Sie können den Dispatcher von lifecycleScope nicht direkt ändern — er verwendet Dispatchers.Main.immediate. Innerhalb des Coroutine-Blocks können Sie über withContext zu einem anderen Dispatcher wechseln. Verwenden Sie für Tests TestDispatcher mit LifecycleOwner.
lifecycleScope wird abgebrochen, wenn der LifecycleOwner in den Zustand DESTROYED übergeht (nach onDestroy). Einfache lifecycleScope.launch-Aufrufe werden nicht in onPause oder onStop abgebrochen. Zum Pausieren beim Wechsel in den Hintergrund verwenden Sie repeatOnLifecycle(STARTED) oder repeatOnLifecycle(RESUMED).
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch