lifecycleScope — ce este, legătura cu Lifecycle și lucrul în Android

Autor: IT Sectr Publicat: 2026-06-23 Timp de citire: 9 min

lifecycleScope — este un CoroutineScope încorporat din biblioteca androidx.lifecycle, care este legat de ciclul de viață al Activity, Fragment sau oricărui LifecycleOwner și anulează automat corutinele la distrugerea componentului. Conform Google Android Developers, 2025, lifecycleScope permite lansarea sigură a corutinelor legate de stratul UI fără riscul de a executa cod după distrugerea Activity sau Fragment. Scope se anulează automat la trecerea LifecycleOwner în starea DESTROYED.

Principalele

  • lifecycleScope — CoroutineScope din lifecycle-runtime-ktx, anulat la starea DESTROYED a Lifecycle
  • lifecycleScope.launch — lansarea unei corutine care se anulează automat la distrugerea LifecycleOwner
  • launchWhenStarted / launchWhenResumed — metode învechite, înlocuite cu repeatOnLifecycle
  • repeatOnLifecycle — API modern pentru lansarea corutinelor care urmează o stare specifică Lifecycle
  • Dispatchers.Main.immediate — dispecerul implicit pentru lifecycleScope

Ce este lifecycleScope în Android?

lifecycleScope — este o proprietate de extensie pe interfața LifecycleOwner (Activity, Fragment, Service) care oferă un CoroutineScope gata făcut, legat de ciclul complet de viață al componentului. Când LifecycleOwner ajunge la starea DESTROYED, lifecycleScope anulează automat toate corutinele active.

kotlin
// În Fragment sau Activity
lifecycleScope.launch {
    delay(1000)
    showSnackbar("Salut!")
}

Spre deosebire de viewModelScope, lifecycleScope se anulează la fiecare distrugere a LifecycleOwner — inclusiv la rotirea ecranului. Acest lucru îl face ideal pentru operațiile care trebuie să trăiască doar cât timp un ecran specific este vizibil.

Unde este disponibil lifecycleScope

lifecycleScope este disponibil oriunde există LifecycleOwner:

  • Activity — AppCompatActivity moștenește LifecycleOwner
  • Fragment — Fragment moștenește LifecycleOwner
  • LifecycleService — serviciu cu ciclu de viață
  • ProcessLifecycleOwner — ciclul de viață al întregii aplicații
  • LifecycleOwner personalizat — orice obiecte care implementează LifecycleOwner

Cum funcționează lifecycleScope: Lifecycle și anularea automată

Mecanismul de anulare automată a lifecycleScope se bazează pe abonarea la evenimentele Lifecycle. Când Lifecycle coboară sub CREATED la DESTROYED, scope este anulat.

Stările Lifecycle

StareDescriereScope activ
CREATEDLifecycleOwner creat, onCreate executatDa
STARTEDLifecycleOwner vizibil (onStart)Da
RESUMEDLifecycleOwner în prim-plan (onResume)Da
DESTROYEDLifecycleOwner distrus (onDestroy)Nu (scope anulat)

Structura internă a lifecycleScope

lifecycleScope este creat ca CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate) și stocat în interiorul Lifecycle. La trecerea Lifecycle în starea DESTROYED este apelat scope.cancel(). Mecanismul este implementat prin LifecycleEventObserver, care se abonează la evenimentele ciclului de viață la prima accesare a scope.

Comportamentul la rotire

La rotirea ecranului, Activity este distrus (onDestroy) și recreat. lifecycleScope este anulat împreună cu Activity veche și o nouă instanță a scope este creată pentru noua Activity. Aceasta este o diferență fundamentală față de viewModelScope, care se păstrează la rotire.

API lifecycleScope: launch, launchWhen și repeatOnLifecycle

Biblioteca lifecycle oferă mai multe moduri de a lansa corutine prin lifecycleScope. Să analizăm evoluția API de la metodele învechite la cele moderne.

lifecycleScope.launch — lansarea de bază

Cea mai simplă modalitate — lifecycleScope.launch { ... }. Corutina se lansează imediat și se anulează la DESTROYED. Totuși, poate executa cod chiar și când UI nu este vizibil (de exemplu, în fundal după onStop). Acest lucru nu este întotdeauna de dorit.

Învechite: launchWhenCreated / launchWhenStarted / launchWhenResumed

Aceste metode suspendau execuția corutinei când Lifecycle cobora sub starea specificată și o reluau la revenire. Însă au fost marcate ca @Deprecated în lifecycle-runtime-ktx 2.6.0, deoarece:

  • Nu anulau corutina — doar o suspendau
  • Duceau la acumularea de corutine suspendate consumatoare de memorie
  • Creau race condition la comutarea rapidă a stărilor

API modern: repeatOnLifecycle

repeatOnLifecycle — modul recomandat de Google pentru lansarea corutinelor sincronizate cu ciclul de viață. Anulează și repornește corutina de fiecare dată când Lifecycle atinge o stare specificată.

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

Corutina transmisă în repeatOnLifecycle se lansează când Lifecycle atinge STARTED și se anulează când coboară sub STARTED. La revenirea în STARTED, corutina se repornește de la început. Acest lucru este sigur și eficient — nicio corutină nu rămâne suspendată.

flowWithLifecycle — pentru Flow

Pentru colectarea datelor din Flow cu luarea în considerare a ciclului de viață există operatorul flowWithLifecycle. Acesta oprește și reia automat colectarea la schimbarea stării Lifecycle:

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

Operatorul flowWithLifecycle — cel mai concis mod de abonare sigură la Flow în stratul UI.

Exemple de utilizare lifecycleScope

Să analizăm trei scenarii reale de aplicare a lifecycleScope într-o aplicație Android în Kotlin.

Exemplul 1: Abonarea la actualizări de locație doar când ecranul este vizibil

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

Corutina pornește când fragmentul devine vizibil (STARTED) și se anulează când părăsește ecranul (STOPPED). Dacă utilizatorul comută pe altă aplicație, actualizările de locație nu consumă bateria.

Exemplul 2: Lansarea animației la pornirea fragmentului

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

Animația se lansează doar când fragmentul este în prim-plan (RESUMED). Dacă utilizatorul minimizează aplicația în timpul animației, corutina este anulată, iar la revenire animația se lansează din nou.

Exemplul 3: Sincronizarea periodică a datelor pe ecranul vizibil

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

Datele sunt sincronizate la fiecare 30 de secunde, dar doar când ecranul este vizibil. isActive verifică dacă corutina nu a fost anulată, asigurând ieșirea sigură din buclă la părăsirea ecranului.

lifecycleScope vs viewModelScope: scenarii de aplicare

Ambele scope sunt legate de ciclul de viață, dar de aspecte diferite ale acestuia. Înțelegerea diferenței este critică pentru arhitectura corectă a aplicațiilor Android.

Diferența cheie

viewModelScope este legat de ViewModel, care supraviețuiește rotirii ecranului. lifecycleScope este legat de LifecycleOwner (Activity/Fragment), care la rotire este distrus și recreat. Aceasta determină scenariile de aplicare.

Când să folosiți lifecycleScope

  • Abonarea la evenimente sistemice (locație, senzori, cameră)
  • Animații și efecte UI legate de un ecran specific
  • Încărcarea datelor în porțiuni cu luarea în considerare a vizibilității ecranului
  • Operații care trebuie să înceteze la părăsirea ecranului

Când să folosiți viewModelScope

  • Încărcarea datelor din Repository
  • Logica de business care trebuie să supraviețuiască rotirii
  • Cache și procesarea datelor
  • Orice operații al căror rezultat este necesar după rotire

Utilizarea combinată

În practică, combinația ambelor scope este frecventă: viewModelScope încarcă datele și gestionează starea, lifecycleScope se abonează la Flow din ViewModel cu luarea în considerare a ciclului de viață al ecranului. Această separare a responsabilităților este considerată best practice în dezvoltarea modernă Android.

Erori tipice la lucrul cu lifecycleScope

Să analizăm patru dintre cele mai frecvente erori pe care le fac dezvoltatorii la utilizarea lifecycleScope.

Eroarea 1: Folosirea lifecycleScope în loc de viewModelScope pentru încărcarea datelor

Dacă lansați încărcarea datelor în lifecycleScope.launch, la rotirea ecranului corutina va fi anulată și datele vor trebui reîncărcate. Utilizați viewModelScope pentru operații de lungă durată. lifecycleScope — doar pentru sarcini legate de UI.

Eroarea 2: Colectarea Flow fără repeatOnLifecycle

Apelul direct viewModel.someFlow.collect { ... } în interiorul lifecycleScope.launch continuă să colecteze date chiar și când ecranul nu este vizibil. Acest lucru poate duce la actualizări UI în fundal și costuri suplimentare. Folosiți întotdeauna repeatOnLifecycle sau flowWithLifecycle.

Eroarea 3: Uitarea anulării la părăsirea ecranului

Deși lifecycleScope se anulează la DESTROYED, codul de după punctul de suspendare (suspend) poate să nu se execute la anularea bruscă. Nu vă bazați pe executarea codului după un apel suspend, decât dacă folosiți NonCancellable.

Eroarea 4: Folosirea învechitului launchWhenStarted în loc de repeatOnLifecycle

launchWhenStarted și analogii săi nu anulează corutina, ci doar o suspendă. Dacă ecranul comută de mai multe ori între prim-plan și fundal, corutina acumulează apeluri amânate. Migrați la repeatOnLifecycle — acesta este singurul mod corect de sincronizare cu Lifecycle.

Întrebări frecvente

Care este diferența dintre lifecycleScope și GlobalScope?

lifecycleScope se anulează automat la distrugerea LifecycleOwner. GlobalScope trăiește pe tot timpul de funcționare a aplicației. Corutina în lifecycleScope nu poate actualiza UI după distrugerea componentului, în GlobalScope — poate, ceea ce duce la erori. Folosiți întotdeauna lifecycleScope în stratul UI.

Se poate folosi lifecycleScope în ViewModel?

Nu, ViewModel nu este LifecycleOwner, deci lifecycleScope nu este disponibil în el. ViewModel folosește viewModelScope. Dacă codul trebuie executat în ambele contexte — extrăgeți logica în use case sau repository cu funcții suspend.

Ce se întâmplă la apelarea repetată a repeatOnLifecycle?

Fiecare apel repeatOnLifecycle creează o nouă corutină care lansează blocul la atingerea stării specificate Lifecycle. Dacă repeatOnLifecycle este apelat de două ori pentru aceeași stare, ambele blocuri vor fi lansate independent. De obicei, un singur apel în onViewCreated este suficient.

Se poate seta un Dispatcher personalizat pentru lifecycleScope?

Nu se poate schimba direct dispecerul lifecycleScope — acesta folosește Dispatchers.Main.immediate. În interiorul blocului corutinei puteți comuta pe un alt dispecer prin withContext. Pentru teste, utilizați TestDispatcher cu LifecycleOwner.

lifecycleScope se anulează în onPause sau onDestroy?

lifecycleScope se anulează la trecerea LifecycleOwner în starea DESTROYED (după onDestroy). Apelurile simple lifecycleScope.launch nu se anulează în onPause sau onStop. Pentru pauză la trecerea în fundal, folosiți repeatOnLifecycle(STARTED) sau repeatOnLifecycle(RESUMED).

Concluzii

  • lifecycleScope — CoroutineScope legat de LifecycleOwner, anulat automat la DESTROYED prin LifecycleEventObserver
  • Dispatchers.Main.immediate — dispecerul implicit care asigură actualizarea sigură a UI fără comutări inutile
  • repeatOnLifecycle — API modern pentru lansarea corutinelor într-o stare specificată Lifecycle cu anulare și repornire automată
  • flowWithLifecycle — operator pentru colectarea sigură a Flow din UI cu luarea în considerare a ciclului de viață
  • launchWhenStarted este învechit — în loc de suspendare, folosiți repeatOnLifecycle care anulează corutina, nu o suspendă
  • lifecycleScope vs viewModelScope — lifecycleScope pentru operații UI (animații, locație), viewModelScope pentru date și logică de business
  • Rotirea ecranului — lifecycleScope se anulează la rotire, viewModelScope se păstrează; alegeți scope în funcție de sarcină

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și