Not Running — co to je, počáteční stav životního cyklu

Autor: IT Sectr Publikováno: 2026-03-03 Doba čtení: 11 min

Not Running — počáteční stav životního cyklu mobilní aplikace, ve kterém aplikace ještě nebyla spuštěna nebo již ukončila činnost. Zjistěte, jak systém iOS a Android spravuje tento stav, jaké události vedou k přechodu z Not Running a jak správně zpracovat spuštění a ukončení aplikace v Swift a Kotlin.

Hlavní body

  • Not Running — aplikace není načtena do paměti a nevykonává kód, je to vstupní a výstupní bod v životním cyklu
  • Spuštění — přechod z Not Running nastává při klepnutí na ikonu, přes deep link nebo push oznámení
  • Ukončení — uživatel zavře aplikaci přejetím, systém ji uvolní při nedostatku paměti nebo dojde k crash
  • Studený start — aplikace startuje od nuly, všechny objekty jsou vytvořeny znovu, stav není obnoven z mezipaměti
  • Teplý start — aplikace byla v Suspended a vrací se do Active bez úplné inicializace

Not Running — co je to za stav

Not Running — je základní stav životního cyklu mobilní aplikace, ve kterém aplikace není načtena do RAM zařízení a nespotřebovává systémové prostředky. V iOS a Android tento stav znamená úplnou absenci procesů a vláken spojených s aplikací. Uživatel vidí ikonu aplikace na ploše, ale samotná aplikace není aktivní a nenachází se v seznamu nedávných.

Když uživatel klepne na ikonu, systém vytvoří nový proces, načte spustitelný kód do paměti a inicializuje všechny potřebné datové struktury. Tento proces se nazývá studený start (cold start) a je nejnáročnější z hlediska doby načítání.

Systém může přesunout aplikaci do Not Running z jakéhokoli jiného stavu. Pokud je aplikace na pozadí (Background) nebo pozastavena (Suspended), operační systém má právo ji uvolnit při nedostatku RAM pro prioritnější úkoly — například pro aktivní aplikaci v popředí.

Vývojář musí mít na paměti, že aplikace může být systémem ukončena kdykoli, když je na pozadí. To znamená, že všechna neuložená data mohou být ztracena. Proto je kriticky důležité ukládat stav do úložišť klíč-hodnota (UserDefaults, SharedPreferences) nebo do lokální databáze při přechodech z Active do Background.

Jak systém určuje, kterou aplikaci uvolnit

iOS používá priority na základě aktuálního stavu aplikace: Active má nejvyšší prioritu, poté Inactive, Background, Suspended a nakonec Not Running — minimální prioritu. Android používá podobnou hierarchii procesů: proces Foreground má prioritu OOM_ADJ = 0, proces Visible = 100, proces Service = 200, proces Background = 300, proces Empty = 400. Čím vyšší hodnota, tím větší pravděpodobnost, že proces bude ukončen při nedostatku paměti.

PlatformaStavPriorita uvolněníPopis
iOSNot RunningNejvyššíAplikace není načtena — systémový prostředek nespotřebováván
iOSSuspendedVysokáAplikace v paměti, ale kód není vykonáván — první cíl pro uvolnění
iOSBackgroundStředníAplikace vykonává úlohu na pozadí — uvolněna po vypršení časového limitu
iOSActiveNízkáAktivní aplikace — uvolněna pouze při kritickém nedostatku paměti
AndroidEmpty ProcessNejvyššíProces bez aktivních komponent — odstraněn první
AndroidBackground ProcessVysokáProces na pozadí bez viditelného Activity
AndroidForeground ServiceNízkáSlužba s oznámením — zřídka ukončena
AndroidForeground ProcessMinimálníAktivní Activity — ukončeno jako poslední

Studený a teplý start aplikace

Studený start (cold start) nastává, když aplikace přechází z Not Running přímo do Active. Systém vytvoří nový proces, načte třídy, inicializuje statická pole, vytvoří hlavní vlákno a spustí UI framework. V iOS to znamená volání application(_:didFinishLaunchingWithOptions:), v Android — volání Application.onCreate() a Activity.onCreate(). Doba studeného startu se může pohybovat od 200 ms do několika sekund v závislosti na složitosti aplikace.

Teplý start (warm start nebo hot start) — aplikace byla ve stavu Suspended a vrací se do provozu bez úplného znovunačtení. Systém obnoví poslední zásobník UI z paměti a uživatel pokračuje v práci na stejném místě. Teplý start je výrazně rychlejší než studený, protože většina kódu je již načtena v paměti. V iOS teplý start nevolá application(_:didFinishLaunchingWithOptions:), pouze applicationWillEnterForeground a applicationDidBecomeActive.

Rozdíl mezi studeným a teplým startem je kritický pro uživatelský zážitek. Při studeném startu musí vývojář zajistit, aby spuštění proběhlo co nejrychleji — líná inicializace modulů, odložené načítání těžkých zdrojů, minimalizace práce v hlavním vlákně při startu. Google doporučuje studený start ne delší než 500 ms, Apple — ne delší než 400 ms pro iOS.

kotlin
// Měření doby studeného startu v Android
class App : Application() {
    private var startTime: Long = 0L

    override fun onCreate() {
        super.onCreate()
        startTime = System.currentTimeMillis()
    }

    fun getStartupTime(): Long {
        return System.currentTimeMillis() - startTime
    }
}

// Spuštění Activity s línou inicializací
class MainActivity : AppCompatActivity() {
    private val viewModel: MainViewModel by lazy {
        ViewModelProvider(this).get(MainViewModel::class.java)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // Pouze nezbytné minimum pro první snímek
        setupNavigation()
    }

    override fun onPostCreate(savedInstanceState: Bundle?) {
        super.onPostCreate(savedInstanceState)
        // Těžká inicializace po vykreslení
        initializeHeavyModules()
    }
}

Příklad ukazuje měření doby studeného startu v Android. Application.onCreate() je volán při přechodu z Not Running do Active. Časové razítko je zaznamenáno při startu procesu. Activity používá línou inicializaci přes lazy-delegát, aby neblokoval první snímek. onPostCreate je optimální místo pro inicializaci těžkých modulů, protože UI je již vykresleno.

Not Running v iOS: Swift a AppDelegate

V iOS je Not Running spravováno přes delegáta UIApplicationDelegate. Klíčové metody: application(_:didFinishLaunchingWithOptions:) je volán po studeném startu, applicationWillTerminate(_:) je volán před ukončením aplikace uživatelem. Systém může ukončit aplikaci bez volání applicationWillTerminate — například při nouzovém ukončení nebo uvolnění paměti. iOS nezaručuje volání této metody, proto by data měla být ukládána v applicationDidEnterBackground.

Scénáře přechodu do Not Running na iOS

Uživatel může ručně ukončit aplikaci přejetím v App Switcher. Systém může uvolnit aplikaci z paměti na pozadí. Aplikace může nouzově skončit (crash). Ve všech případech jsou všechny objekty vytvořené během spuštění zničeny. Stav, který nebyl uložen, je nenávratně ztracen. V iOS 13+ pro ukládání stavu se doporučuje používat NSUserActivity nebo mechanismus state restoration přes UIApplication.stateRestorationIdentifier.

swift
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    // Studený start: aplikace přešla z Not Running
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        // Inicializace minimální sady služeb
        setupAnalytics()
        configureAppearance()
        return true
    }

    // Aplikace ukončuje činnost — pouze ruční zavření
    func applicationWillTerminate(
        _ application: UIApplication
    ) {
        saveCriticalData()
    }

    // Ukládání dat před přechodem na pozadí
    func applicationDidEnterBackground(
        _ application: UIApplication
    ) {
        saveApplicationState()
    }

    private func saveCriticalData() {
        UserDefaults.standard.synchronize()
    }

    private func saveApplicationState() {
        let state = ["lastScreen": "main", "timestamp": Date()]
        try? NSKeyedArchiver.archivedData(
            withRootObject: state,
            requiringSecureCoding: true
        )
    }
}

Kód ukazuje správné zpracování Not Running v iOS. applicationWillTerminate je volán pouze při ručním ukončení uživatelem. Ukládání kritických dat je duplikováno v applicationDidEnterBackground, protože tato metoda je zaručeně volána před přechodem na pozadí. State restoration umožňuje uložit zásobník UI pro pozdější obnovení při studeném startu.

Not Running v Android: Kotlin a proces

V Android Not Running znamená, že proces aplikace neexistuje. Linuxový systém, na kterém je Android založen, spravuje procesy prostřednictvím mechanismu Zygote. Při spuštění aplikace Zygote forknout nový proces, načte Dalvik/ART a zavolá Application.onCreate(). V Android neexistuje přímý analog applicationWillTerminate — systém může proces kdykoli ukončit bez varování.

Životní cyklus procesu Android

Když je Activity poprvé voláno, systém vytvoří proces, Application a Activity prostřednictvím řetězce onCreate → onStart → onResume. Pokud uživatel stiskne Back, Activity je zničeno (onDestroy) a proces může být systémem ukončen. Klíčový rozdíl oproti iOS: v Android může proces nadále existovat i bez aktivních Activity — například pokud běží Foreground Service nebo je aktivní BroadcastReceiver.

kotlin
// Zpracování Not Running přes SavedStateHandle ve ViewModel
class MainViewModel(
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {

    companion object {
        private const val KEY_LAST_SCREEN = "last_screen"
        private const val KEY_USER_DATA = "user_data"
    }

    fun saveCurrentState(screen: String, data: String) {
        savedStateHandle[KEY_LAST_SCREEN] = screen
        savedStateHandle[KEY_USER_DATA] = data
    }

    fun restoreState(): AppState? {
        val screen = savedStateHandle.get<String>(KEY_LAST_SCREEN)
        val data = savedStateHandle.get<String>(KEY_USER_DATA)
        return if (screen != null && data != null) {
            AppState(screen, data)
        } else null
    }
}

// Application — první zpětné volání po Not Running
class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        initCrashReporter()
        initDependencyInjection()
    }
}

SavedStateHandle — komponenta Android Architecture Components, která automaticky ukládá stav při přechodu do Not Running a obnovuje jej při studeném startu. ViewModel vytvořený přes ViewModelProvider přežije otočení obrazovky a zničení Activity. Při ukončení procesu jsou data z SavedStateHandle serializována do Bundle a uložena v saved instance state.

Důvody přechodu do Not Running

Not Running nastává z několika důvodů. Uživatel ručně zavře aplikaci. Systém uvolní aplikaci při nedostatku paměti. Aplikace nouzově skončí s výjimkou. V Android může systém ukončit proces při hromadné aktualizaci aplikací nebo restartu zařízení. iOS může ukončit aplikaci při vypršení časového limitu úlohy na pozadí (obvykle 30 sekund).

DůvodiOSAndroidMožnost prevence
Ruční zavření uživatelemPřejetí v App SwitcherPřejetí z RecentsNe — akce uživatele
Nedostatek pamětiAktivace memory warningonTrimMemory / LMKČástečně — optimalizace paměti
Crash aplikaceNSException / signálUncaughtException / ANRAno — zpracování chyb a crash-reporting
Časový limit úlohy na pozadí30 s pro Background task10 min pro JobSchedulerAno — správné plánování úloh
Restart OSVolání applicationWillTerminateBroadcast ACTION_SHUTDOWNNe — systémová událost
Aktualizace aplikaceNenastává (iOS Sandbox)Proces končí při aktualizaci APKNe — systémová aktualizace

Jak diagnostikovat přechod do Not Running

Pro iOS použijte konzolové logování v applicationWillTerminate a applicationDidFinishLaunching. Přidejte příznak do UserDefaults při každém spuštění — pokud při příštím startu příznak chybí, aplikace byla ukončena nesprávně. V Android použijte ActivityManager.isBackgroundRestricted() pro kontrolu, zda aplikace může spouštět úlohy na pozadí. Sledujte také onTrimMemory(TRIM_MEMORY_COMPLETE) — to je signál, že proces bude ukončen.

Nejlepší postupy práce s Not Running

První pravidlo — nikdy nepředpokládejte, že applicationWillTerminate nebo onDestroy budou volány. Ukládejte kriticky důležitá data při každém přechodu z Active do Background. Používejte úložiště klíč-hodnota pro jednoduchá nastavení a SQLite/Room pro strukturovaná data.

Druhé pravidlo — měřte dobu studeného startu a optimalizujte ji. Líná inicializace, minimalizace práce v hlavním vlákně, předběžné načítání zdrojů, použití SplashScreen API — to vše zlepšuje vnímání doby spuštění. Google doporučuje studený start pod 200 ms pro vynikající UX.

Třetí pravidlo — implementujte State Restoration. V iOS používejte UIApplication.stateRestorationIdentifier a NSUserActivity. V Android používejte SavedStateHandle ve ViewModel v kombinaci s onSaveInstanceState. To uživateli umožní pokračovat v práci na stejném místě po restartu aplikace.

Čtvrté pravidlo — zpracovávejte launchOptions a Intent, se kterými byla aplikace spuštěna po Not Running. Deep linky, push oznámení, univerzální odkazy — všechny jsou předávány prostřednictvím parametrů spuštění. Vývojář musí tato data správně extrahovat a nasměrovat uživatele na odpovídající obrazovku.

swift
// Zpracování deep link po studeném startu
func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
    // Kontrola, zda přišlo oznámení
    if let notification = launchOptions?[.remoteNotification] as? [String: Any] {
        handleNotification(notification)
    }
    // Kontrola deep link
    if let url = launchOptions?[.url] as? URL {
        handleDeepLink(url)
    }
    return true
}

private func handleDeepLink(_ url: URL) {
    guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
          let screenId = components.queryItems?.first(where: { $0.name == "screen" })?.value
    else { return }
    openScreen(screenId)
}

Kód ukazuje zpracování parametrů spuštění při studeném startu v iOS. launchOptions obsahuje data, se kterými systém aplikaci spustil. Oznámení, deep linky a univerzální odkazy jsou předávány prostřednictvím tohoto slovníku. Vývojář musí správně zpracovat všechny možné scénáře spuštění, aby zajistil bezproblémový uživatelský zážitek.

Často kladené otázky

Co se stane s daty při přechodu do Not Running?

Data, která byla uložena v trvalém úložišti (UserDefaults, Core Data, SharedPreferences, Room), jsou zachována. Data v RAM — proměnné, mezipaměť, stav ViewModel bez SavedStateHandle — jsou nenávratně ztracena. Proto je kriticky důležité ukládat stav aplikace při každém přechodu na pozadí.

Jak odlišit studený start od teplého na iOS?

Při studeném startu se volá application(_:didFinishLaunchingWithOptions:). Při teplém startu (návrat z Suspended) se tato metoda nevolá — aktivují se pouze applicationWillEnterForeground a applicationDidBecomeActive. Pokud potřebujete provést akci pouze při studeném startu, nastavte příznak v didFinishLaunchingWithOptions.

Může být Android aplikace v Not Running s aktivním Service?

Ano. Foreground Service s trvalým oznámením zabraňuje ukončení procesu systémem, i když jsou všechna Activity zničena. Background Service (startService bez foreground) může být systémem kdykoli zastaven. Běžící Service znamená, že proces existuje a už se nejedná o Not Running.

Jak emulovat Not Running na simulátoru?

Na iOS simulátoru ukončete aplikaci přes App Switcher (Cmd+Shift+H dvakrát, přejeďte nahoru). Na Android emulátoru použijte adb shell am force-stop com.example.app nebo tlačítko Stop v Logcat. Poté aplikaci znovu spusťte — to bude čistý studený start z Not Running.

Co je kill-switch v kontextu Not Running?

Kill-switch — serverový příkaz pro nouzové ukončení aplikace. Používá se v bankovních a podnikových aplikacích pro vzdálené blokování přístupu. Pokud aplikace obdržela kill příkaz, při příštím studeném startu zablokuje UI a vyžádá opětovnou autorizaci. V iOS je kill-switch implementován prostřednictvím remote notifications s příznakem blokování.

Shrnutí

  • Not Running — počáteční a konečný stav životního cyklu, aplikace není načtena do paměti a nevykonává kód
  • Studený start — úplné znovunačtení aplikace z Not Running, vyžaduje inicializaci všech komponent od nuly
  • Teplý start — návrat z Suspended, nevolá didFinishLaunchingWithOptions ani Application.onCreate
  • Ukládání dat — kriticky důležité při přechodu do Background, protože Not Running může nastat kdykoli
  • iOS — applicationWillTerminate není zaručeno, stav se ukládá přes UserDefaults nebo state restoration
  • Android — proces může být ukončen kdykoli, SavedStateHandle ve ViewModel ukládá stav automaticky
  • Optimalizace startu — líná inicializace, minimální práce v main thread, SplashScreen API pro rychlý první snímek

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é