App Lifecycle: co to je, stavy aplikace v iOS a Android

Autor: IT Sectr Publikováno: 2026-03-02 Doba čtení: 8 min
App Lifecycle (životní cyklus aplikace) — posloupnost stavů, kterými prochází mobilní aplikace od spuštění do ukončení. Porozumění lifecycle je kritické pro správu zdrojů, ukládání dat a zajištění stability. V iOS aplikace prochází stavy: Not Running → Active → Inactive → Background → Suspended. V Android — přes onCreate → onStart → onResume → onPause → onStop → onDestroy + onRestart. Každý stav dává vývojáři okno pro uložení stavu, uvolnění zdrojů nebo přípravu na návrat. Podle Apple Documentation je ignorování lifecycle událostí příčinou 40% pádů při minimalizaci aplikace. V IT Sectr jsme implementovali ProcessLifecycleOwner v Android a šablonu AppDelegate v iOS jako povinné standardy pro všechny projekty — to snížilo počet chyb souvisejících s pozadím o 60%.

Hlavní body

  • App Lifecycle — sada stavů aplikace: od spuštění do ukončení, každý s určitými akcemi vývojáře.
  • AppDelegate — centrální třída iOS pro zpracování lifecycle: didFinishLaunching, didEnterBackground, willEnterForeground.
  • SceneDelegate — delegát jednotlivé scény (iOS 13+), spravuje lifecycle každého okna v aplikacích s více okny.
  • ProcessLifecycleOwner — Android komponent z AndroidX Lifecycle, sledující lifecycle celého procesu.
  • Application.onCreate — první vstupní bod Android aplikace, volá se před jakoukoliv Activity.

Co je App Lifecycle?

App Lifecycle — konečný automat popisující všechny možné stavy mobilní aplikace a přechody mezi nimi. Každý stav určuje, zda aplikace může vykonávat kód, zobrazovat UI a spotřebovávat zdroje. iOS a Android mají podobný, ale ne identický model — rozdíly vyplývají z architektury OS: iOS používá přísnou kontrolu paměti (stav suspended), Android — flexibilní správu procesů přes onSaveInstanceState.

V iOS je lifecycle pevně svázán s foreground/background: aplikace je buď aktivní, nebo pozastavena. V Android je lifecycle více granulární — Activity/Window prochází 6+ stavy a samotný proces má další lifecycle přes ProcessLifecycleOwner. Moderní aplikace (od 2024) stále častěji používají architektonické vzory založené na lifecycle: SwiftUI Lifecycle (iOS 16+) přes .scenePhase environment, Compose Lifecycle přes LifecycleEventObserver. Tyto vzory automaticky zpracovávají přepínání kontextu a zabraňují únikům paměti. Podle Google správné zpracování lifecycle v Android snižuje spotřebu paměti o 30–40% při práci na pozadí.

Životní cyklus iOS: AppDelegate a SceneDelegate

V iOS je lifecycle aplikace spravován přes třídu UIApplicationDelegate (AppDelegate). Hlavní metody: application(_:didFinishLaunchingWithOptions:) — inicializace při prvním spuštění; applicationDidBecomeActive — aplikace viditelná a připravená k interakci; applicationWillResignActive — přechod do neaktivního stavu (příchozí hovor, zavření závěsu); applicationDidEnterBackground — aplikace skrytá, je ~5 sekund na uložení dat; applicationWillEnterForeground — návrat z pozadí; applicationWillTerminate — ukončení (volá se pouze pro staré aplikace bez suspended).

Od iOS 13 Apple zavedl SceneDelegate (UISceneDelegate) pro podporu aplikací s více okny na iPad a macOS Catalyst. SceneDelegate spravuje lifecycle každé jednotlivé scény (okna): scene(_:willConnectTo:options:) — vytvoření scény; sceneDidBecomeActive — scéna aktivní; sceneWillResignActive — scéna ztrácí fokus; sceneDidEnterBackground — scéna skrytá. AppDelegate odpovídá za globální události (načítání dat, push notifikace) a SceneDelegate — za stav UI každého okna. V SwiftUI je lifecycle spravován přes environment hodnotu @Environment(\.scenePhase): .active, .inactive, .background — to poskytuje jednotné API pro SwiftUI a UIKit aplikace.

Životní cyklus Android: Application a ProcessLifecycleOwner

V Android lifecycle začíná třídou Application — singletonem, který je vytvořen před jakoukoliv Activity. Metoda Application.onCreate() — první vstupní bod, používaný pro globální inicializaci (Analytics, DI, Crash Reporting). Poté je Activity spuštěna s posloupností: onCreate() → onStart() → onResume(). Při minimalizaci: onPause() → onStop() → onSaveInstanceState(). Při zničení: onDestroy(). Při návratu: onRestart() → onStart() → onResume().

ProcessLifecycleOwner (z AndroidX Lifecycle 2.2+) sleduje lifecycle celého procesu, nikoli jednotlivé Activity. Poskytuje dva stavy: ON_RESUME (aplikace v foreground) a ON_STOP (aplikace skrytá). ProcessLifecycleOwner řeší problém "kdy aplikace přešla na pozadí" na úrovni procesu — to je kritické pro SDK, knihovny a modulární aplikace. V Jetpack Compose je lifecycle spravován přes LifecycleEventObserver a collectAsStateWithLifecycle, který automaticky pozastavuje sběr dat v režimu pozadí. Android 14 (API 34) přidal oznámení o foreground service lifecycle přes Service.onTimeout — služba musí skončit do 6 hodin, jinak ji systém vynuceně zastaví.

Srovnání lifecycle iOS a Android

iOSAndroidPopis
Not RunningAplikace není spuštěna
didFinishLaunchingApplication.onCreatePrvní inicializace při spuštění
ActiveonResumeAplikace viditelná a přijímá vstup
InactiveonPauseDočasná ztráta fokusu (hovor, závěs)
BackgroundonStopAplikace skrytá, kód může být vykonáván
SuspendedKód se nevykonává, paměť rezervována
Will TerminateonDestroyAplikace se ukončuje

Hlavní rozdíl: iOS vynuceně převádí aplikaci do Suspended (kód se nevykonává) 5-10 sekund po přechodu na pozadí. Android povoluje práci na pozadí (služby, WorkManager) po delší dobu, ale s omezeními Doze Mode (Android 6+) a omezeními pozadí (Android 12+). ProcessLifecycleOwner v Android — analog UIApplicationDidEnterBackgroundNotification v iOS s tím rozdílem, že se aktivuje při každém přechodu na pozadí, nejen po ztrátě fokusu.

Příklady kódu

iOS: AppDelegate s lifecycle metodami

Základní implementace AppDelegate se zpracováním všech stavů životního cyklu. Ukládání dat při přechodu na pozadí a aktualizace UI při návratu.

swift
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_: UIApplication, didFinishLaunchingWithOptions lo: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { Analytics.shared.initialize(); return true }
    func applicationDidBecomeActive(_: UIApplication) { NotificationCenter.default.post(name: .appDidBecomeActive, object: nil) }
    func applicationWillResignActive(_: UIApplication) { NotificationCenter.default.post(name: .appWillResignActive, object: nil) }
    func applicationDidEnterBackground(_: UIApplication) { CoreDataManager.shared.saveContext(); UserDefaults.standard.synchronize() }
    func applicationWillEnterForeground(_: UIApplication) { NetworkManager.shared.refreshSession() }
}

AppDelegate — centrální bod lifecycle. applicationDidEnterBackground — kritická metoda: iOS dává ~5 sekund na uložení dat. applicationDidBecomeActive — aktualizujte UI, restartujte animace. Pro SceneDelegate (iOS 13+) je logika lifecycle rozdělena na scény: sceneDidBecomeActive / sceneDidEnterBackground spravují jednotlivá okna.

iOS: SceneDelegate (iOS 13+)

SceneDelegate pro aplikace s více okny na iPad. Každá scéna má vlastní lifecycle, nezávislý na ostatních oknech.

swift
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?
    func scene(_: UIScene, willConnectTo s: UISceneSession, options o: UIScene.ConnectionOptions) {
        guard let ws = (_ as? UIWindowScene) else { return }
        window = UIWindow(windowScene: ws)
        window?.rootViewController = ViewController()
        window?.makeKeyAndVisible()
    }
    func sceneDidBecomeActive(_: UIScene) { PlayerManager.shared.resume() }
    func sceneDidEnterBackground(_: UIScene) { PlayerManager.shared.pause(); CoreDataManager.shared.saveContext() }
    func sceneDidDisconnect(_: UIScene) { PlayerManager.shared.cleanup() }
}

SceneDelegate spravuje lifecycle jednotlivé scény. sceneDidBecomeActive / sceneDidEnterBackground — ekvivalent metod AppDelegate pro konkrétní okno. sceneDidDisconnect se volá při zavření scény (uživatel zavřel okno na iPad). Pro zachování kompatibility s iOS 12 a nižším musí AppDelegate duplikovat logiku SceneDelegate. V iOS 17+ můžete použít @Observable pro automatické pozastavení/obnovení úkolů na základě scenePhase.

Android: Application s ProcessLifecycleOwner

ProcessLifecycleOwner sleduje, kdy je aplikace v foreground/background na úrovni procesu. To je optimální způsob globální správy lifecycle.

kotlin
import android.app.Application
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
class MainApplication : Application() {
    override fun onCreate() { super.onCreate(); ProcessLifecycleOwner.get().lifecycle.addObserver(AppLifecycleObserver()) }
}
class AppLifecycleObserver : LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_START) fun onEnterForeground() { Analytics.shared.onForeground(); NetworkMonitor.shared.start() }
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP) fun onEnterBackground() { Analytics.shared.onBackground(); NetworkMonitor.shared.stop() }
}

ProcessLifecycleOwner — jediný správný způsob sledování přechodu na pozadí na úrovni aplikace. ON_START se aktivuje, když se aplikace stane viditelnou (foreground), ON_STOP — když je zcela skryta (background). Na rozdíl od Activity lifecycle, ProcessLifecycleOwner není vázán na konkrétní obrazovku. Pro Jetpack Compose použijte LifecycleResumeEffect nebo collectAsStateWithLifecycle místo ručního pozorování.

Android: Activity Lifecycle s ViewModel

ViewModel + Lifecycle — správná Android architektura pro práci s lifecycle. ViewModel se automaticky čistí při onDestroy, zabraňuje únikům paměti.

kotlin
import androidx.lifecycle.ViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
class TimerViewModel : ViewModel() {
    private val _time = MutableLiveData<Long>()
    val time: LiveData<Long> = _time
    private var startTime = System.currentTimeMillis()
    init { updateTime() }
    private fun updateTime() { _time.value = System.currentTimeMillis() - startTime }
    override fun onCleared() { super.onCleared(); Logger.d("ViewModel cleared — uvolnění zdrojů") }
}
// V Activity
class TimerActivity : AppCompatActivity() {
    private val viewModel: TimerViewModel by viewModels()
    override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState); Logger.d("Activity created") }
    override fun onResume() { super.onResume(); viewModel.time.observe(this) { Logger.d("Time: $it") } }
    override fun onPause() { super.onPause(); Logger.d("Activity paused — pozastavení animací") }
    override fun onDestroy() { super.onDestroy(); Logger.d("Activity destroyed — čištění") }
}

ViewModel přežije otočení obrazovky a je zničen pouze při finish() Activity. onCleared() — místo pro uvolnění zdrojů, odhlášení z datových proudů. LiveData automaticky pozastavuje pozorování při onPause a obnovuje při onResume — poskytuje ochranu před úniky a pády během práce na pozadí. V Compose použijte collectAsStateWithLifecycle() pro stejný účel.

Často kladené otázky

Co se stane, když uživatel minimalizuje iOS aplikaci?

Při minimalizaci aplikace přechází z active do inactive (krátce), poté do background. Po několika sekundách ji systém může převést do suspended — kód se nevykonává, paměť je rezervována. Při nedostatku paměti je suspended aplikace ukončena (willTerminate se nevolá). Ukládejte data v applicationDidEnterBackground — to je poslední garantovaný bod pro uložení.

Je třeba zpracovávat všechny stavy App Lifecycle?

Minimálně povinné: applicationDidEnterBackground — uložte uživatelská data; applicationWillEnterForeground — aktualizujte UI; v Android onPause — pozastavte animace/senzory. ProcessLifecycleOwner zjednodušuje zpracování: onResume — onPause pro foreground, onStart — onStop pro viditelnost. Ostatní stavy zpracovávejte podle potřeby — ne všechny stavy jsou kritické pro každou aplikaci.

Čím se liší SceneDelegate od AppDelegate?

AppDelegate — globální delegát celé aplikace (spuštění, přechod na pozadí). SceneDelegate (iOS 13+) spravuje lifecycle jednotlivého okna (scény) — v aplikacích s více okny na iPad má každá scéna vlastní lifecycle. Pro iOS 12 a nižší je celý lifecycle zpracováván přes AppDelegate. Od iPadOS 16+ je SceneDelegate povinný pro Stage Manager.

Co je ProcessLifecycleOwner v Android?

ProcessLifecycleOwner — komponent z AndroidX Lifecycle, který sleduje lifecycle celé aplikace (procesu), nikoli jednotlivé Activity. Poskytuje dvě hlavní události: ON_RESUME (aplikace v foreground) a ON_STOP (aplikace v background). Používá se pro inicializaci/čištění SDK, analytiky, síťových monitorů — všeho, co by mělo reagovat na přechod aplikace na pozadí, bez ohledu na aktuální obrazovku.

Jak spravovat lifecycle v Jetpack Compose?

V Jetpack Compose použijte LifecycleEventObserver přes LocalLifecycleOwner.current.lifecycle nebo funkci collectAsStateWithLifecycle(). Pro Compose obrazovky aplikujte LifecycleResumeEffect — analog DisposableEffect, který se spouští při onResume a čistí při onPause. lifecycleScope.launchWhenResumed — korutina automaticky pozastavená na pozadí.

Shrnutí

  • App Lifecycle — konečný automat stavů aplikace určující správu zdrojů, ukládání dat a stabilitu.
  • iOS AppDelegate (applicationDidEnterBackground) — kritická metoda pro ukládání dat při přechodu na pozadí do 5 sekund.
  • iOS SceneDelegate (iOS 13+) spravuje lifecycle každé scény zvlášť — povinný pro aplikace s více okny na iPad.
  • Android ProcessLifecycleOwner — globální pozorovatel lifecycle procesu pro inicializaci/čištění SDK.
  • ViewModel v Android přežije otočení obrazovky a čistí se při finish Activity — zabraňuje únikům paměti.
  • SwiftUI @Environment(\.scenePhase) — jednotné API pro lifecycle v SwiftUI (active, inactive, background).
  • Správné zpracování lifecycle snižuje spotřebu paměti o 30-40% a zabraňuje 40% pádů během práce na pozadí.

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í.

Prodiskutovat projekt

Přečtěte si také