LifecycleOwner — je klíčové rozhraní z knihovny Android Jetpack, které deklaruje, že objekt má životní cyklus a poskytuje k němu přístup prostřednictvím metody getLifecycle(). Leží v základu komponentové architektury moderních Android aplikací a umožňuje oddělit logiku práce s životním cyklem od konkrétní implementace Activity nebo Fragment. Podle údajů Google I/O 2024 používá více než 85 % nových projektů na Androidu LifecycleOwner pro správu předplatných a prevenci úniků paměti. Toto rozhraní je základem pro LiveData, ViewModel a další komponenty Jetpack a zajišťuje bezpečné provádění kódu pouze v aktivním stavu komponenty.
Hlavní body
LifecycleOwner — je rozhraní z balíčku androidx.lifecycle, které obsahuje jedinou metodu getLifecycle(), jež vrací objekt Lifecycle. Tento objekt sleduje aktuální stav komponenty (CREATED, STARTED, RESUMED, DESTROYED) a při jeho změně informuje všechny přihlášené pozorovatele. LifecycleOwner je součástí Architecture Components a patří do knihovny lifecycle-runtime.
Hlavním úkolem rozhraní je standardizace přístupu k životnímu cyklu. Před příchodem Jetpacku používali vývojáři ruční přihlašování v onStart a odhlašování v onStop, což vedlo k duplicitě kódu a chybám. LifecycleOwner tento problém řeší poskytnutím jednotného mechanismu pro všechny komponenty Android. Místo explicitního volání metod životního cyklu se vývojář jednou přihlásí k Lifecycle a oznámení přicházejí automaticky.
Rozhraní je deklarováno v Kotlin jako funkcionální rozhraní s jednou abstraktní metodou:
interface LifecycleOwner {
val lifecycle: Lifecycle
}
Díky funkcionálnímu charakteru rozhraní je snadné jej implementovat pomocí delegáta nebo lambdy. To je obzvláště výhodné pro vytváření Custom Views a tříd ViewModel, které musí reagovat na změny životního cyklu hostitele. Objekt Lifecycle získaný z getLifecycle() poskytuje metody addObserver a removeObserver pro správu předplatných.
LifecycleOwner funguje ve spojení se dvěma klíčovými třídami: Lifecycle a LifecycleObserver. Lifecycle ukládá aktuální stav komponenty jako enum State (INITIALIZED, CREATED, STARTED, RESUMED, DESTROYED) a sleduje přechody mezi nimi. Když se stav změní, Lifecycle informuje všechny registrované pozorovatele voláním příslušných anotovaných metod. Tento mechanismus se nazývá „lifecycle-aware" — kód se provádí pouze tehdy, když je komponenta v odpovídajícím stavu.
Mechanismus předávání událostí je založen na vzoru Observer. LifecycleOwner hraje roli Observable a implementace LifecycleObserver hraje roli Observer. Activity nebo Fragment při změně svého stavu (onCreate → onStart → onResume → onPause → onStop → onDestroy) informuje Lifecycle prostřednictvím vnitřního mechanismu ReportFragment, který se automaticky přidává do systému AndroidX. Vývojář nemusí ručně volat metody Lifecycle — vše probíhá automaticky.
| Stav Lifecycle | Událost | |
|---|---|---|
| Metoda životního cyklu Android | ||
| INITIALIZED | — | Před onCreate |
| CREATED | ON_CREATE | onCreate |
| STARTED | ON_START | onStart |
| RESUMED | ON_RESUME | onResume |
| STARTED | ON_PAUSE | onPause |
| CREATED | ON_STOP | onStop |
| DESTROYED | ON_DESTROY | onDestroy |
Existují dva způsoby, jak se přihlásit k událostem LifecycleOwner: klasický LifecycleObserver s anotacemi a moderní DefaultLifecycleObserver s explicitními metodami. Druhý přístup doporučuje Google od roku 2022, protože poskytuje lepší typovou bezpečnost a vyhýbá se reflexi, která se používala v anotačním přístupu. DefaultLifecycleObserver vyžaduje Java 8+ nebo Kotlin a je preferován pro nové projekty.
Příklad přihlášení prostřednictvím DefaultLifecycleObserver:
class MyObserver : DefaultLifecycleObserver {
override fun onStart(owner: LifecycleOwner) {
// Spuštění GPS sledování pouze když je komponenta aktivní
startLocationUpdates()
}
override fun onStop(owner: LifecycleOwner) {
// Bezpečné zastavení při přechodu do režimu na pozadí
stopLocationUpdates()
}
}
// Připojení:
lifecycleOwner.lifecycle.addObserver(MyObserver())
Každá metoda DefaultLifecycleObserver přijímá LifecycleOwner jako parametr. To umožňuje pozorovateli přistupovat ke kontextu prováděné komponenty bez nutnosti jej předávat samostatně. Tento přístup činí kód modulárnějším a testovatelnějším — Observer není závislý na konkrétní implementaci Activity nebo Fragment, ale pracuje s abstrakcí LifecycleOwner.
Starý způsob s použitím anotace @OnLifecycleEvent se stále vyskytuje ve starších projektech, ale jeho použití se nedoporučuje pro nový kód. Reflexe potřebná pro zpracování anotací přidává režii a může vést k chybám, které nejsou odhaleny ve fázi kompilace. Google oficiálně doporučuje migraci na DefaultLifecycleObserver.
// Zastaralý přístup — nedoporučuje se pro nové projekty
class MyLegacyObserver : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onStart() {
startLocationUpdates()
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun onStop() {
stopLocationUpdates()
}
}
Anotační přístup má významný nedostatek: chybějící kontrolu životnosti Observeru. Pokud vývojář zapomene odhlásit Observer při zničení LifecycleOwner, objekt Observer zůstane v paměti až do spuštění garbage collectoru. DefaultLifecycleObserver tento problém řeší — Observer je připojen k Lifecycle a automaticky se odhlašuje při přechodu do stavu DESTROYED.
Od AppCompat 1.1.0 a AndroidX Fragment 1.2.0 jsou všechny Activity a Fragment, které dědí z AppCompatActivity nebo Fragment, automaticky LifecycleOwner. To znamená, že metoda getLifecycle() je v nich k dispozici ve výchozím nastavení a přihlašování k událostem životního cyklu funguje bez další konfigurace. Vývojář stačí zavolat lifecycle.addObserver() z libovolného místa v Activity nebo Fragment.
Podívejme se na příklad integrace LifecycleOwner v Activity:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycle.addObserver(LocationObserver(this))
}
}
V tomto příkladu je lifecycle extension property dostupná díky AndroidX Activity. Observer LocationObserver bude automaticky dostávat oznámení o spuštění (ON_START) a zastavení (ON_STOP) Activity. Při otáčení obrazovky je Observer informován o ON_DESTROY a poté o ON_CREATE, což umožňuje správné zpracování změn konfigurace bez dalšího kódu.
Fragment implementuje LifecycleOwner prostřednictvím rozhraní a jeho Lifecycle je vázán na životní cyklus Fragmentu, nikoli na nadřazené Activity. To je důležité: Lifecycle Fragmentu přechází do DESTROYED, když je Fragment odstraněn z transakce, zatímco Activity může zůstat v RESUMED. Tento rozdíl umožňuje Observeru přihlásit se samostatně k životnímu cyklu každé komponenty.
class MyFragment : Fragment() {
private val uiStateObserver = UiStateObserver()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
lifecycle.addObserver(uiStateObserver)
}
}
Důležitou výhodou použití LifecycleOwner ve Fragmentu je automatické odhlášení při přechodu Fragmentu do DESTROYED. To je obzvláště důležité pro ViewPager, kde mohou být Fragmenty dynamicky vytvářeny a ničeny. Ruční správa předplatných v tomto scénáři by byla extrémně složitá a náchylná k chybám.
Rozhraní LifecycleOwner lze implementovat v libovolné třídě, která má životní cyklus. To je užitečné pro Custom Views, Service a dokonce i ViewModel v některých architektonických řešeních. Google poskytuje pomocnou třídu LifecycleRegistry, která spravuje stav Lifecycle a generuje události. Vývojář musí ručně volat příslušné metody LifecycleRegistry při změně stavu komponenty.
Příklad implementace LifecycleOwner v Custom View:
class MyCustomView(
context: Context,
attrs: AttributeSet?
) : FrameLayout(context, attrs), LifecycleOwner {
private val lifecycleRegistry = LifecycleRegistry(this)
override val lifecycle: Lifecycle
get() = lifecycleRegistry
fun onStart() {
lifecycleRegistry.setCurrentState(Lifecycle.State.STARTED)
}
fun onStop() {
lifecycleRegistry.setCurrentState(Lifecycle.State.CREATED)
}
}
V tomto příkladu LifecycleRegistry funguje jako úložiště stavu. Metody onStart/onStop by měla volat nadřazená komponenta (např. Activity), když se Custom View stane viditelným nebo skryje. LifecycleRegistry automaticky vypočítává potřebné události pro přechod mezi stavy a informuje všechny přihlášené Observery.
Při implementaci vlastního LifecycleOwner je důležité dodržovat pravidlo: stav LifecycleRegistry by měl být aktualizován jako poslední v příslušné metodě životního cyklu, po všech ostatních operacích. To zaručuje, že Observery obdrží oznámení, když je komponenta plně připravena na nový stav. Použití LifecycleRegistry.createUnsafe jako alternativy je také možné, ale vyžaduje opatrnost s vlákny.
LifecycleOwner je základem pro několik klíčových komponent Android Jetpack. LiveData používá LifecycleOwner k určení aktivního stavu a automatickému odhlášení při zničení komponenty. ViewModel přímo neimplementuje LifecycleOwner, ale může získat Lifecycle prostřednictvím SavedStateHandle. Navigation Component používá LifecycleOwner pro správu předplatných v NavBackStackEntry. Pochopení této souvislosti pomáhá budovat architekturu aplikace na pevném základě.
Interakce LiveData s LifecycleOwner:
class ExampleActivity : AppCompatActivity() {
private val viewModel: ExampleViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.userData.observe(this) { data ->
// this — LifecycleOwner (Activity)
// Kód se provádí pouze když je Activity ve stavu RESUMED
updateUI(data)
}
}
}
LiveData vyžaduje LifecycleOwner v metodě observe(), protože to zaručuje, že aktualizace uživatelského rozhraní proběhnou pouze v aktivním stavu. Pokud je Activity na pozadí, LiveData uchovává poslední hodnotu, ale neinformuje Observer. Při návratu do RESUMED obdrží Observer aktuální hodnotu bez dalších požadavků na síť nebo databázi.
DataBinding také používá LifecycleOwner pro vázání observable polí k životnímu cyklu Activity nebo Fragment. To umožňuje předcházet únikům paměti v kombinaci ViewModel + DataBinding — všechna předplatná jsou automaticky vyčištěna při zničení LifecycleOwner. Tento přístup činí kód deklarativním a bezpečným.
Správné použití LifecycleOwner vyžaduje dodržování několika klíčových pravidel. První a nejdůležitější: vždy přihlašujte Observer v onCreate/onViewCreated, ne později. To zaručuje, že Observer obdrží počáteční stav Lifecycle (CREATED po onCreate) a nezmešká události. Druhé pravidlo: používejte DefaultLifecycleObserver místo anotačního přístupu pro všechny nové projekty.
Moderní přístup k práci s korutinami a LifecycleOwner — rozšíření repeatOnLifecycle:
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.flow.collect { value ->
updateUI(value)
}
}
}
Tento vzor zaručuje, že collect na Flow je aktivní pouze ve stavu STARTED nebo RESUMED. Při přechodu do STOPPED je kolekce automaticky zrušena a při návratu do STARTED — znovu spuštěna. repeatOnLifecycle nahrazuje ruční odhlašování z Flow ve Fragmentu a je doporučeným přístupem Google pro práci s asynchronními datovými toky v komponentách uživatelského rozhraní.
Další důležité doporučení: nezneužívejte LifecycleObserver pro logiku nesouvisející s životním cyklem. Pokud má komponenta provést akci v určitém stavu, ale nevyžaduje odhlášení při zničení, je lepší použít explicitní volání metod v onStart/onStop. LifecycleObserver je ospravedlnitelný pro dlouho žijící komponenty (LocationListener, SensorManager), kde je ruční správa předplatných složitá a náchylná k chybám.
Často kladené otázky
LifecycleOwner — je rozhraní, které deklaruje, že objekt má životní cyklus. Lifecycle — je třída, která ukládá aktuální stav a spravuje Observer. LifecycleOwner poskytuje Lifecycle prostřednictvím getLifecycle().
Ne, Lifecycle automaticky odhlašuje všechny Observery při přechodu do DESTROYED. To je jedna z hlavních výhod LifecycleOwner — vývojář nemusí ručně volat removeObserver v onDestroy.
Fragment implementuje LifecycleOwner prostřednictvím rozhraní AndroidX fragmentů. Jeho Lifecycle je vázán na životní cyklus Fragmentu odděleně od Activity. To umožňuje Observeru reagovat na události Fragmentu, nikoli nadřazené Activity.
Ano, k tomu se používá LifecycleRegistry. Custom View musí implementovat rozhraní LifecycleOwner a ručně aktualizovat stav LifecycleRegistry při změně viditelnosti nebo připojení k oknu.
LifecycleOwner řeší jiný úkol: správu předplatných na události životního cyklu, nikoli rušení korutin. Pro korutiny se používá lifecycleScope, který automaticky ruší spuštěné korutiny při zničení LifecycleOwner.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také