lifecycleScope — wat het is, koppeling met Lifecycle en werken in Android

Auteur: IT Sectr Gepubliceerd: 2026-06-23 Leestijd: 9 min

lifecycleScope — is een ingebouwde CoroutineScope uit de androidx.lifecycle-bibliotheek, die is gekoppeld aan de levenscyclus van Activity, Fragment of elke LifecycleOwner en automatisch coroutines annuleert bij vernietiging van de component. Volgens Google Android Developers, 2025 maakt lifecycleScope het mogelijk om veilig coroutines te starten die aan de UI-laag zijn gekoppeld, zonder het risico code uit te voeren na vernietiging van Activity of Fragment. De scope wordt automatisch geannuleerd wanneer LifecycleOwner de status DESTROYED bereikt.

Belangrijkste punten

  • lifecycleScope — CoroutineScope uit lifecycle-runtime-ktx, geannuleerd bij DESTROYED-status van Lifecycle
  • lifecycleScope.launch — starten van een coroutine die automatisch wordt geannuleerd bij vernietiging van LifecycleOwner
  • launchWhenStarted / launchWhenResumed — verouderde methoden, vervangen door repeatOnLifecycle
  • repeatOnLifecycle — moderne API voor het starten van coroutines die een specifieke Lifecycle-status volgen
  • Dispatchers.Main.immediate — standaard dispatcher voor lifecycleScope

Wat is lifecycleScope in Android?

lifecycleScope — is een extensie-eigenschap op de LifecycleOwner-interface (Activity, Fragment, Service) die een kant-en-klare CoroutineScope biedt die is gekoppeld aan de volledige levenscyclus van de component. Wanneer LifecycleOwner de status DESTROYED bereikt, annuleert lifecycleScope automatisch alle actieve coroutines.

kotlin
// In Fragment of Activity
lifecycleScope.launch {
    delay(1000)
    showSnackbar("Hallo!")
}

In tegenstelling tot viewModelScope wordt lifecycleScope geannuleerd bij elke vernietiging van LifecycleOwner — inclusief schermrotatie. Dit maakt het ideaal voor bewerkingen die alleen moeten leven zolang een specifiek scherm zichtbaar is.

Waar is lifecycleScope beschikbaar

lifecycleScope is overal beschikbaar waar een LifecycleOwner is:

  • Activity — AppCompatActivity erft van LifecycleOwner
  • Fragment — Fragment erft van LifecycleOwner
  • LifecycleService — service met levenscyclus
  • ProcessLifecycleOwner — levenscyclus van de hele applicatie
  • Aangepaste LifecycleOwner — alle objecten die LifecycleOwner implementeren

Hoe werkt lifecycleScope: Lifecycle en automatische annulering

Het mechanisme voor automatische annulering van lifecycleScope is gebaseerd op abonnement op Lifecycle-gebeurtenissen. Wanneer Lifecycle onder CREATED naar DESTROYED zakt, wordt de scope geannuleerd.

Lifecycle-statussen

StatusBeschrijvingScope actief
CREATEDLifecycleOwner aangemaakt, onCreate uitgevoerdJa
STARTEDLifecycleOwner zichtbaar (onStart)Ja
RESUMEDLifecycleOwner op de voorgrond (onResume)Ja
DESTROYEDLifecycleOwner vernietigd (onDestroy)Nee (scope geannuleerd)

Interne structuur van lifecycleScope

lifecycleScope wordt aangemaakt als CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate) en opgeslagen in Lifecycle. Bij overgang van Lifecycle naar de status DESTROYED wordt scope.cancel() aangeroepen. Het mechanisme is geïmplementeerd via LifecycleEventObserver, die zich bij eerste toegang tot de scope abonneert op levenscyclusgebeurtenissen.

Gedrag bij rotatie

Bij schermrotatie wordt Activity vernietigd (onDestroy) en opnieuw aangemaakt. lifecycleScope wordt samen met de oude Activity geannuleerd en een nieuw exemplaar van de scope wordt aangemaakt voor de nieuwe Activity. Dit is een fundamenteel verschil met viewModelScope, die behouden blijft bij rotatie.

lifecycleScope API: launch, launchWhen en repeatOnLifecycle

De lifecycle-bibliotheek biedt verschillende manieren om coroutines te starten via lifecycleScope. Laten we de evolutie van de API van verouderde naar moderne methoden bekijken.

lifecycleScope.launch — basis start

De eenvoudigste manier — lifecycleScope.launch { ... }. De coroutine start onmiddellijk en wordt geannuleerd bij DESTROYED. Het kan echter code uitvoeren zelfs wanneer UI niet zichtbaar is (bijvoorbeeld op de achtergrond na onStop). Dit is niet altijd wenselijk.

Verouderd: launchWhenCreated / launchWhenStarted / launchWhenResumed

Deze methoden onderbraken de uitvoering van de coroutine wanneer Lifecycle onder de opgegeven status zakte en hervatten bij terugkeer. Ze zijn echter gemarkeerd als @Deprecated in lifecycle-runtime-ktx 2.6.0, omdat:

  • Ze de coroutine niet annuleerden — alleen onderbraken
  • Ze leidden tot ophoping van hangende coroutines die geheugen verbruiken
  • Ze race conditions creëerden bij snel schakelen van statussen

Moderne API: repeatOnLifecycle

repeatOnLifecycle — de door Google aanbevolen manier om coroutines te starten die zijn gesynchroniseerd met de levenscyclus. Het annuleert en herstart de coroutine elke keer wanneer Lifecycle een opgegeven status bereikt.

kotlin
lifecycleScope.launch {
    repeatOnLifecycle(Lifecycle.State.STARTED) {
        viewModel.uiState.collect { state ->
            updateUI(state)
        }
    }
}

De coroutine die aan repeatOnLifecycle wordt doorgegeven, start wanneer Lifecycle STARTED bereikt en wordt geannuleerd wanneer het onder STARTED zakt. Bij terugkeer naar STARTED wordt de coroutine opnieuw gestart. Dit is veilig en efficiënt — geen enkele coroutine blijft in pauze hangen.

flowWithLifecycle — voor Flow

Voor het verzamelen van gegevens uit Flow met inachtneming van de levenscyclus is er de operator flowWithLifecycle. Deze stopt en hervat automatisch het verzamelen bij verandering van de Lifecycle-status:

kotlin
viewModel.uiState
    .flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
    .onEach { state -> updateUI(state) }
    .launchIn(lifecycleScope)

De operator flowWithLifecycle — de meest beknopte manier voor veilig abonneren op Flow in de UI-laag.

Voorbeelden van lifecycleScope-gebruik

Laten we drie realistische scenario's bekijken voor het gebruik van lifecycleScope in een Android-app in Kotlin.

Voorbeeld 1: Abonneren op locatie-updates alleen wanneer het scherm zichtbaar is

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)
                }
            }
        }
    }
}

De coroutine start wanneer het fragment zichtbaar wordt (STARTED) en wordt geannuleerd wanneer het scherm wordt verlaten (STOPPED). Als de gebruiker naar een andere app schakelt, verbruiken locatie-updates geen batterij.

Voorbeeld 2: Starten van animatie bij opstarten van fragment

kotlin
lifecycleScope.launch {
    repeatOnLifecycle(Lifecycle.State.RESUMED) {
        animateFadeIn(titleView)
        delay(200)
        animateSlideUp(contentView)
    }
}

De animatie start alleen wanneer het fragment op de voorgrond is (RESUMED). Als de gebruiker de app minimaliseert tijdens de animatie, wordt de coroutine geannuleerd en bij terugkeer wordt de animatie opnieuw gestart.

Voorbeeld 3: Periodieke gegevenssynchronisatie op zichtbaar scherm

kotlin
lifecycleScope.launch {
    repeatOnLifecycle(Lifecycle.State.STARTED) {
        while (isActive) {
            syncData()
            delay(30_000L)
        }
    }
}

Gegevens worden elke 30 seconden gesynchroniseerd, maar alleen wanneer het scherm zichtbaar is. isActive controleert of de coroutine niet is geannuleerd, wat een veilige uitgang uit de lus bij het verlaten van het scherm garandeert.

lifecycleScope vs viewModelScope: toepassingsscenario's

Beide scopes zijn gekoppeld aan de levenscyclus, maar aan verschillende aspecten ervan. Het begrijpen van het verschil is cruciaal voor de juiste architectuur van Android-applicaties.

Belangrijkste verschil

viewModelScope is gekoppeld aan ViewModel, die schermrotatie overleeft. lifecycleScope is gekoppeld aan LifecycleOwner (Activity/Fragment), die bij rotatie wordt vernietigd en opnieuw aangemaakt. Dit bepaalt de toepassingsscenario's.

Wanneer lifecycleScope gebruiken

  • Abonneren op systeemgebeurtenissen (locatie, sensoren, camera)
  • Animaties en UI-effecten gekoppeld aan een specifiek scherm
  • Gefaseerd laden van gegevens rekening houdend met zichtbaarheid van scherm
  • Bewerkingen die moeten stoppen bij het verlaten van het scherm

Wanneer viewModelScope gebruiken

  • Gegevens laden uit Repository
  • Bedrijfslogica die rotatie moet overleven
  • Cachen en verwerken van gegevens
  • Alle bewerkingen waarvan het resultaat na rotatie nodig is

Gecombineerd gebruik

In de praktijk komt een combinatie van beide scopes vaak voor: viewModelScope laadt gegevens en beheert de status, lifecycleScope abonneert zich op Flow van ViewModel rekening houdend met de levenscyclus van het scherm. Deze scheiding van verantwoordelijkheden wordt beschouwd als best practice in moderne Android-ontwikkeling.

Veelgemaakte fouten bij het werken met lifecycleScope

Laten we vier veelgemaakte fouten bekijken die ontwikkelaars maken bij het gebruik van lifecycleScope.

Fout 1: Gebruik van lifecycleScope in plaats van viewModelScope voor het laden van gegevens

Als u het laden van gegevens start in lifecycleScope.launch, wordt de coroutine bij schermrotatie geannuleerd en moeten de gegevens opnieuw worden geladen. Gebruik viewModelScope voor langdurige bewerkingen. lifecycleScope — alleen voor UI-gerelateerde taken.

Fout 2: Flow verzamelen zonder repeatOnLifecycle

Directe aanroep van viewModel.someFlow.collect { ... } binnen lifecycleScope.launch blijft gegevens verzamelen zelfs wanneer het scherm niet zichtbaar is. Dit kan leiden tot UI-updates op de achtergrond en onnodige overhead. Gebruik altijd repeatOnLifecycle of flowWithLifecycle.

Fout 3: Vergeten van annulering bij het verlaten van het scherm

Hoewel lifecycleScope wordt geannuleerd bij DESTROYED, kan code na een suspend-punt mogelijk niet worden uitgevoerd bij plotselinge annulering. Vertrouw niet op uitvoering van code na een suspend-aanroep, tenzij u NonCancellable gebruikt.

Fout 4: Gebruik van verouderde launchWhenStarted in plaats van repeatOnLifecycle

launchWhenStarted en zijn analogen annuleren de coroutine niet, maar onderbreken deze alleen. Als het scherm meerdere keren schakelt tussen voor- en achtergrond, accumuleert de coroutine uitgestelde aanroepen. Stap over op repeatOnLifecycle — dit is de enige juiste manier om met Lifecycle te synchroniseren.

Veelgestelde vragen

Wat is het verschil tussen lifecycleScope en GlobalScope?

lifecycleScope wordt automatisch geannuleerd bij vernietiging van LifecycleOwner. GlobalScope leeft gedurende de hele looptijd van de applicatie. Een coroutine in lifecycleScope kan UI niet bijwerken na vernietiging van de component, in GlobalScope kan dat wel, wat leidt tot crashes. Gebruik altijd lifecycleScope in de UI-laag.

Kan lifecycleScope worden gebruikt in ViewModel?

Nee, ViewModel is geen LifecycleOwner, dus lifecycleScope is er niet beschikbaar. ViewModel gebruikt viewModelScope. Als code in beide contexten moet worden uitgevoerd — haal de logica dan uit naar use case of repository met suspend-functies.

Wat gebeurt er bij herhaalde aanroep van repeatOnLifecycle?

Elke repeatOnLifecycle-aanroep maakt een nieuwe coroutine aan die het blok start bij het bereiken van de opgegeven Lifecycle-status. Als repeatOnLifecycle tweemaal wordt aangeroepen voor dezelfde status, worden beide blokken onafhankelijk gestart. Meestal is één aanroep in onViewCreated voldoende.

Kan een aangepaste Dispatcher worden ingesteld voor lifecycleScope?

De dispatcher van lifecycleScope kan niet direct worden gewijzigd — het gebruikt Dispatchers.Main.immediate. Binnen het coroutine-blok kunt u via withContext naar een andere dispatcher schakelen. Gebruik voor tests TestDispatcher met LifecycleOwner.

Wordt lifecycleScope geannuleerd in onPause of onDestroy?

lifecycleScope wordt geannuleerd bij overgang van LifecycleOwner naar de status DESTROYED (na onDestroy). Eenvoudige lifecycleScope.launch-aanroepen worden niet geannuleerd in onPause of onStop. Gebruik voor pauzeren bij overgang naar de achtergrond repeatOnLifecycle(STARTED) of repeatOnLifecycle(RESUMED).

Samenvatting

  • lifecycleScope — CoroutineScope gekoppeld aan LifecycleOwner, automatisch geannuleerd bij DESTROYED via LifecycleEventObserver
  • Dispatchers.Main.immediate — standaard dispatcher die veilige UI-updates garandeert zonder onnodige schakelingen
  • repeatOnLifecycle — moderne API voor het starten van coroutines in een opgegeven Lifecycle-status met automatische annulering en herstart
  • flowWithLifecycle — operator voor veilig verzamelen van Flow vanuit UI met inachtneming van de levenscyclus
  • launchWhenStarted is verouderd — gebruik in plaats van onderbreken repeatOnLifecycle, die de coroutine annuleert in plaats van onderbreekt
  • lifecycleScope vs viewModelScope — lifecycleScope voor UI-bewerkingen (animaties, locatie), viewModelScope voor gegevens en bedrijfslogica
  • Schermrotatie — lifecycleScope wordt geannuleerd bij rotatie, viewModelScope blijft behouden; kies scope afhankelijk van de taak

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook