lifecycleScope — egy beépített CoroutineScope az androidx.lifecycle könyvtárból, amely az Activity, Fragment vagy bármely LifecycleOwner életciklusához van kötve, és automatikusan törli a korutinokat a komponens megsemmisülésekor. A Google Android Developers, 2025 szerint a lifecycleScope lehetővé teszi az UI réteghez kapcsolódó korutinok biztonságos indítását anélkül, hogy fennállna a kód végrehajtásának kockázata az Activity vagy Fragment megsemmisülése után. A scope automatikusan törlődik, amikor a LifecycleOwner DESTROYED állapotba lép.
Főbb pontok
lifecycleScope — egy kiterjesztési tulajdonság a LifecycleOwner (Activity, Fragment, Service) interfészen, amely egy kész CoroutineScope-ot biztosít, amely a komponens teljes életciklusához van kötve. Amikor a LifecycleOwner eléri a DESTROYED állapotot, a lifecycleScope automatikusan törli az összes aktív korutint.
// Fragmentben vagy Activity-ben
lifecycleScope.launch {
delay(1000)
showSnackbar("Helló!")
}
A viewModelScope-tól eltérően a lifecycleScope minden LifecycleOwner megsemmisülésekor törlődik — beleértve a képernyő-forgatást is. Ez ideálissá teszi olyan műveletekhez, amelyeknek csak addig kell élniük, amíg egy adott képernyő látható.
lifecycleScope mindenhol elérhető, ahol LifecycleOwner van:
A lifecycleScope automatikus törlésének mechanizmusa a Lifecycle eseményekre való feliratkozáson alapul. Amikor a Lifecycle a CREATED alá esik DESTROYED-be, a scope törlődik.
| Állapot | Leírás | Scope aktív |
|---|---|---|
| CREATED | LifecycleOwner létrehozva, onCreate végrehajtva | Igen |
| STARTED | LifecycleOwner látható (onStart) | Igen |
| RESUMED | LifecycleOwner előtérben (onResume) | Igen |
| DESTROYED | LifecycleOwner megsemmisítve (onDestroy) | Nem (scope törölve) |
A lifecycleScope CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate) ként jön létre, és a Lifecycle-en belül tárolódik. Amikor a Lifecycle DESTROYED állapotba lép, a scope.cancel() hívódik meg. A mechanizmus LifecycleEventObserver-n keresztül valósul meg, amely a scope első elérésekor feliratkozik az életciklus eseményekre.
A képernyő forgatásakor az Activity megsemmisül (onDestroy) és újrateremtődik. A lifecycleScope törlődik a régi Activity-vel együtt, és egy új scope példány jön létre az új Activity számára. Ez alapvető különbség a viewModelScope-tól, amely megmarad forgatáskor.
A Lifecycle könyvtár több módot kínál korutinok indítására a lifecycleScope-on keresztül. Tekintsük át az API evolúcióját az elavult módszerektől a modernekig.
A legegyszerűbb mód — lifecycleScope.launch { ... }. A korutin azonnal elindul és DESTROYED-nél törlődik. Azonban kódot hajthat végre akkor is, amikor az UI nem látható (pl. háttérben onStop után). Ez nem mindig kívánatos.
Ezek a metódusok felfüggesztették a korutin végrehajtását, amikor a Lifecycle a megadott állapot alá esett, és folytatták visszatéréskor. Azonban @Deprecated-ként lettek megjelölve a lifecycle-runtime-ktx 2.6.0-ban, mert:
repeatOnLifecycle — a Google által ajánlott mód az életciklussal szinkronizált korutinok indítására. Minden alkalommal törli és újraindítja a korutint, amikor a Lifecycle elér egy megadott állapotot.
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect { state ->
updateUI(state)
}
}
}
A repeatOnLifecycle-be átadott korutin akkor indul, amikor a Lifecycle eléri a STARTED-et, és törlődik, amikor a STARTED alá esik. A STARTED-be való visszatéréskor a korutin újraindul. Ez biztonságos és hatékony — egyetlen korutin sem lóg a szünetben.
A Flow-ból történő adatgyűjtéshez az életciklus figyelembevételével létezik a flowWithLifecycle operátor. Automatikusan leállítja és folytatja a gyűjtést a Lifecycle állapotának változásakor:
viewModel.uiState
.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
.onEach { state -> updateUI(state) }
.launchIn(lifecycleScope)
A flowWithLifecycle operátor — a legtömörebb mód a Flow biztonságos feliratkozására az UI rétegben.
Tekintsünk három valós forgatókönyvet a lifecycleScope használatára egy Android alkalmazásban Kotlin nyelven.
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)
}
}
}
}
}
A korutin akkor indul, amikor a fragment láthatóvá válik (STARTED), és törlődik, amikor elhagyja a képernyőt (STOPPED). Ha a felhasználó másik alkalmazásra vált, a helyzetfrissítések nem fogyasztják az akkumulátort.
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.RESUMED) {
animateFadeIn(titleView)
delay(200)
animateSlideUp(contentView)
}
}
Az animáció csak akkor indul, amikor a fragment az előtérben van (RESUMED). Ha a felhasználó minimalizálja az alkalmazást az animáció alatt, a korutin törlődik, és visszatéréskor az animáció újraindul.
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
while (isActive) {
syncData()
delay(30_000L)
}
}
}
Az adatok 30 másodpercenként szinkronizálódnak, de csak amikor a képernyő látható. Az isActive ellenőrzi, hogy a korutin nem lett-e törölve, biztosítva a biztonságos kilépést a ciklusból a képernyő elhagyásakor.
Mindkét scope az életciklushoz van kötve, de annak különböző aspektusaihoz. A különbség megértése kritikus fontosságú az Android alkalmazások helyes architektúrájához.
viewModelScope a ViewModel-hez van kötve, amely túléli a képernyő-forgatást. lifecycleScope a LifecycleOwner-hez (Activity/Fragment) van kötve, amely forgatáskor megsemmisül és újrateremtődik. Ez határozza meg alkalmazási forgatókönyveiket.
A gyakorlatban mindkét scope kombinációja gyakran előfordul: a viewModelScope betölti az adatokat és kezeli az állapotot, a lifecycleScope feliratkozik a Flow-ra a ViewModel-ből a képernyő életciklusának figyelembevételével. Ezt a felelősségi szétválasztást best practice-nek tekintik a modern Android fejlesztésben.
Tekintsük át a négy leggyakoribb hibát, amelyeket a fejlesztők elkövetnek a lifecycleScope használatakor.
Ha az adatbetöltést lifecycleScope.launch-ban indítja, a képernyő forgatásakor a korutin törlődik, és az adatokat újra be kell tölteni. Hosszú élettartamú műveletekhez használjon viewModelScope-ot. lifecycleScope — csak UI-hoz kapcsolódó feladatokhoz.
A viewModel.someFlow.collect { ... } közvetlen meghívása lifecycleScope.launch-on belül akkor is folytatja az adatgyűjtést, amikor a képernyő nem látható. Ez háttérben történő UI-frissítésekhez és szükségtelen többletterheléshez vezethet. Mindig használjon repeatOnLifecycle-ot vagy flowWithLifecycle-ot.
Bár a lifecycleScope DESTROYED-nél törlődik, a felfüggesztési pont (suspend) utáni kód nem biztos, hogy végrehajtódik hirtelen törléskor. Ne támaszkodjon a kód végrehajtására suspend hívás után, hacsak nem használ NonCancellable-t.
A launchWhenStarted és analógjai nem törlik a korutint, csak felfüggesztik. Ha a képernyő többször vált előtér és háttér között, a korutin felhalmozza az elhalasztott hívásokat. Váltson repeatOnLifecycle-ra — ez az egyetlen helyes mód a Lifecycle-lel való szinkronizálásra.
Gyakran Ismételt Kérdések
lifecycleScope automatikusan törlődik a LifecycleOwner megsemmisülésekor. GlobalScope az alkalmazás teljes futási ideje alatt él. A lifecycleScope-ban lévő korutin nem frissítheti az UI-t a komponens megsemmisülése után, a GlobalScope-ban igen, ami összeomlásokhoz vezet. Mindig használjon lifecycleScope-ot az UI rétegben.
Nem, a ViewModel nem LifecycleOwner, ezért a lifecycleScope nem érhető el benne. A ViewModel viewModelScope-ot használ. Ha a kódot mindkét kontextusban végre kell hajtani — bontsa ki a logikát use case-be vagy repository-ba suspend függvényekkel.
Minden repeatOnLifecycle hívás új korutint hoz létre, amely a blokkot a megadott Lifecycle állapot elérésekor indítja el. Ha a repeatOnLifecycle-t kétszer hívják ugyanarra az állapotra, mindkét blokk egymástól függetlenül fut. Általában egyszeri hívás az onViewCreated-ben elegendő.
A lifecycleScope dispatchere nem módosítható közvetlenül — Dispatchers.Main.immediate-t használ. A korutin blokkon belül withContext segítségével másik dispatcherre válthat. Tesztekhez használjon TestDispatcher-t LifecycleOwner-rel.
A lifecycleScope a LifecycleOwner DESTROYED állapotába lépésekor törlődik (onDestroy után). Az egyszerű lifecycleScope.launch hívások nem törlődnek onPause-ban vagy onStop-ban. A háttérbe lépéskor történő szüneteltetéshez használjon repeatOnLifecycle(STARTED) vagy repeatOnLifecycle(RESUMED) kifejezést.
Összefoglaló
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is