onStop — co to je, skrytí Activity v životním cyklu Androidu

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

onStop — metoda životního cyklu Activity v Androidu, volaná systémem, když Activity přestane být pro uživatele viditelná. Activity přechází do stavu Stopped poté, co ji nová Activity zcela zakryje, nebo při minimalizaci aplikace. V metodě onStop je vývojář povinen zastavit animace, uvolnit prostředky kamery a senzorů, uložit koncepty zadaných dat. Podle Android Vitals (Google, 2025) snižuje správné zpracování onStop počet ANR (Application Not Responding) při minimalizaci aplikace o 35%. Po onStop může systém zavolat onRestart (návrat na obrazovku) nebo onDestroy (úplné ukončení). Dokumentace Android Developers k životnímu cyklu Activity popisuje onStop jako hranici mezi viditelným a neviditelným stavem.

Hlavní body

  • onStop — metoda volaná při úplné ztrátě viditelnosti Activity, ale Activity je stále v paměti.
  • Po onStop přechází Activity do stavu Stopped — živá v paměti, ale není viditelná a neinteraguje s uživatelem.
  • Systém může zavolat onRestart → onStart → onResume při návratu na Activity nebo onDestroy při ukončení.
  • V onStop je nutné uvolnit prostředky: zastavit animace, vypnout senzory a kameru, uložit dočasná data.
  • Správná implementace onStop — klíčový faktor stability aplikace při multitaskingu a minimalizaci.

Co je onStop v Androidu?

onStop — je callback metoda třídy AppCompatActivity (a jejího předchůdce Activity), kterou volá operační systém Android, když Activity přestane být pro uživatele zcela viditelná. V tomto okamžiku je Activity skryto jiným Activity, dialogovým oknem, systémovým spouštěčem nebo zamykací obrazovkou. Z hlediska životního cyklu následuje onStop po onPause a signalizuje, že Activity již není na obrazovce viditelné, i když samotný objekt Activity a jeho stav zůstávají v paměti.

Když Activity přejde do stavu Stopped (zastaveno), uchovává svůj stav v paměti RAM — všechna pole, hierarchie View a ViewModel zůstávají přístupné. To odlišuje Stopped od zničeného (Destroyed) stavu, kde je Activity zcela odstraněno. System UI může zabít proces aplikace ve stavu Stopped při nedostatku paměti — to je tzv. process death. Vývojář je povinen uložit kritická data (koncepty, pozici posouvání) do onSaveInstanceState(), které se volá před onStop, aby zajistil obnovení při zabití procesu.

Podle specifikace Android Compatibility Definition Document (CDD) pro verzi 14+ má proces ve stavu Stopped nižší prioritu při zabíjení OOM Killerem — nižší než procesy ve fázi Background, ale vyšší než kešované procesy. Podle statistik Google dochází k 68% případů zabití procesů, když je Activity ve stavu Stopped, nikoli Paused.

Kdy se volá onStop: scénáře a pořadí

onStop se volá při úplné ztrátě viditelnosti Activity, bez ohledu na příčinu: spuštění nového Activity nad aktuálním, minimalizace aplikace (stisknutí Home), zamknutí obrazovky, příchozí hovor nebo otevření systémového dialogu. Ve všech těchto případech Activity nejprve obdrží onPause (částečná ztráta fokusu) a poté onStop (úplná ztráta viditelnosti).

Hlavní scénáře volání onStop:

  • Spuštění nového Activity nad aktuálním — aktuální Activity obdrží onPause, poté onStop; nové Activity prochází onCreate → onStart → onResume.
  • Minimalizace aplikace (Home) — Activity přechází do onPause → onStop během 200–300 ms, zůstává v paměti ve stavu Stopped.
  • Zamknutí obrazovky — systém volá onPause → onStop, protože zamykací obrazovka zcela zakrývá Activity.
  • Příchozí hovor — telefonní Activity (Dialer) se spouští nad ním, aktuální Activity přechází do onStop.
  • Přepnutí na jinou aplikaci (Recent Apps) — Activity je skryto, obdrží onStop, ale zůstává v keši procesů.

Je důležité pochopit, že onStop se nevolá při otáčení obrazovky — v tomto případě je Activity zničeno (onPause → onStop → onDestroy) a znovu vytvořeno (onCreate → onStart → onResume). Výjimka — příznak android:configChanges="orientation" v manifestu, při kterém se Activity znovu nevytváří, ale obdrží volání onConfigurationChanged().

onStop v životním cyklu Activity

onStop zaujímá centrální místo v sekvenci životního cyklu Activity mezi viditelným a neviditelným stavem. Úplná sekvence: onCreate → onStart → onResume → (aktivní stav) → onPause → onStop → onDestroy (nebo onRestart → onStart → onResume při návratu).

StavMetodaViditelnostInterakcePaměť
CreatedonCreateNeNeAlokována
StartedonStartČástečnáNePlná
ResumedonResumePlnáAnoPlná
PausedonPauseČástečnáNePlná
StoppedonStopNeNePlná*
DestroyedonDestroyNeNeUvolněna

*Ve stavu Stopped je Activity uchováváno v paměti, ale může být zabito systémem při nedostatku prostředků. Priorita zabíjení procesů Stopped — předposlední, vyšší pouze než prázdné kešované procesy.

onStop a onSaveInstanceState: Systém volá onSaveInstanceState(Bundle) před onStop pro uložení dynamického stavu UI. Vývojář tuto metodu přepisuje, aby do Bundle uložil hodnoty vstupních polí, pozici RecyclerView, vybrané položky. I když Activity není zničeno (uživatel jej pouze minimalizoval a vrátil se), Bundle je předán do onCreate při změnách konfigurace. Google doporučuje ukládat pouze přechodný stav UI — ne data repozitáře nebo ViewModel, které žijí mimo Activity.

Jaké prostředky uvolnit v onStop

V onStop je vývojář povinen uvolnit všechny prostředky, které nejsou potřeba, když Activity není viditelné. To snižuje zátěž baterie, procesoru a paměti a zabraňuje ANR při návratu na aktivitu.

Co uvolnit v onStop:

  • Animace a transitions — zastavte ObjectAnimator, ValueAnimator, ViewPropertyAnimator. Běžící animace neviditelného Activity je plýtvání cykly GPU.
  • Senzory (Sensors) — odhlaste se ze SensorManager (akcelerometr, gyroskop, magnetometr). Senzory spotřebovávají energii, i když je Activity skryté.
  • Kamera a mikrofon — uvolněte Camera2 nebo CameraX, zastavte MediaRecorder. Nechávat kameru aktivní při skrytém Activity je zakázáno politikou Google Play.
  • LocationListener — odhlaste se z FusedLocationProviderClient nebo LocationManager. Geolokace je nejnáročnější prostředek na energii.
  • Network listeners — zavřete WebSocket, zrušte HTTP požadavky, které nejsou potřeba na pozadí.
  • MediaPlayer a ExoPlayer — pozastavte nebo zastavte, pokud by přehrávání nemělo pokračovat na pozadí.

Co nedělat v onStop: Neprovádějte dlouhé operace — ukládání velkých dat do databáze, síťové požadavky, složité výpočty. onStop se provádí na hlavním vlákně a blokuje návrat na Activity. Pro dlouhé operace použijte WorkManager se zpožděním nebo korutiny v viewModelScope. Neuvolňujte prostředky ViewModel — ViewModel přežije onStop a bude použit při návratu.

Rozdíl mezi onStop a onPause

onPause a onStop se liší stupněm ztráty viditelnosti a rozsahem povinných akcí. onPause se volá při částečné ztrátě fokusu (například otevření dialogového okna nebo systémové nabídky), onStop — při úplné ztrátě viditelnosti. Tento rozdíl je důležitý pro výběr, které prostředky uvolnit v každé fázi.

CharakteristikaonPauseonStop
Stupeň viditelnostiČástečně viditelnéZcela neviditelné
FokusZtracenZtracen
Doba prováděníDo 500 msDo 5 s (ANR timeout)
Prostředky k uvolněníKritické (média, kamera)Všechny neviditelné (senzory, animace, location)
ObnovaonResumeonRestart → onStart → onResume
Priorita procesuVysoká (Foreground)Střední (Background)

Obecné pravidlo: v onPause uvolňujte systémové prostředky, které okamžitě ovlivňují uživatelský zážitek jiné aplikace (kamera, přehrávač médií), v onStop — všechny ostatní prostředky, které nejsou potřeba při skrytém Activity. Google doporučuje v onPause ukládat kritická uživatelská data (koncept e-mailu, nastavení), protože onStop nemusí při rychlém přepínání nastat.

onStop → onRestart: návrat na obrazovku

Když se uživatel vrátí na skryté Activity, systém zavolá onRestart → onStart → onResume. Metoda onRestart signalizuje, že se Activity vrací ze stavu Stopped. To je důležitá fáze pro obnovení UI a prostředků, které byly uvolněny v onStop.

Posloupnost volání při návratu:

  • onRestart() — Activity je informováno, že bude znovu zobrazeno. Typické akce: opětovné načtení dat, aktualizace seznamů.
  • onStart() — Activity se stává viditelným, ale ještě není aktivní. Zde se znovu inicializují prostředky uvolněné v onStop.
  • onResume() — Activity získává fokus a je připraveno k interakci. Spouštějí se animace, registrují senzory.

Pokud byl proces aplikace zabit systémem ve stavu Stopped, onCreate se volá místo onRestart a Bundle z onSaveInstanceState se předává pro obnovení stavu. Tento scénář (process death) — jeden z nejčastějších příčin chyb v Android aplikacích: vývojáři implementují onRestart, ale zapomínají zohlednit obnovení přes onCreate po zabití procesu.

Příklady kódu s onStop v Kotlinu

Příklad 1: Základní implementace onStop s uvolněním senzorů

Ukazuje správné odhlášení ze senzorů a zastavení animace při skrytí Activity. Po návratu na obrazovku se prostředky obnoví v onStart.

kotlin
class MainActivity : AppCompatActivity() {
    private lateinit var sensorManager: SensorManager
    private var accelerometer: Sensor? = null
    private var rotationAnimator: ObjectAnimator? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
    }

    override fun onStart() {
        super.onStart()
        accelerometer?.let {
            sensorManager.registerListener(sensorListener, it, SensorManager.SENSOR_DELAY_NORMAL)
        }
        rotationAnimator = ObjectAnimator.ofFloat(findViewById(R.id.icon), "rotation", 0f, 360f)
        rotationAnimator?.apply {
            duration = 3000
            repeatMode = ValueAnimator.RESTART
            repeatCount = ValueAnimator.INFINITE
            start()
        }
    }

    override fun onStop() {
        super.onStop()
        sensorManager.unregisterListener(sensorListener)
        rotationAnimator?.cancel()
    }

    override fun onRestart() {
        super.onRestart()
        Log.d("MainActivity", "Activity se vrací ze stavu Stopped")
    }

    private val sensorListener = SensorEventListener { event, _ ->
        Log.d("MainActivity", "Accel: x=${event.values[0]}, y=${event.values[1]}, z=${event.values[2]}")
    }
}

Kód registruje senzor akcelerometru a spouští nekonečnou rotační animaci v onStart. V onStop se senzor vypíná a animace ruší — to zabraňuje spotřebě baterie při skrytém Activity. Po návratu přes onRestart → onStart se prostředky znovu vytvářejí.

Příklad 2: onStop s ukládáním stavu pomocí SavedStateHandle

Moderní přístup s využitím ViewModel + SavedStateHandle. Data formuláře se automaticky ukládají při onStop bez ručního Bundle.

kotlin
class FormViewModel(
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {
    var email: String
        get() = savedStateHandle["email"] ?: ""
        set(value) { savedStateHandle["email"] = value }

    var message: String
        get() = savedStateHandle["message"] ?: ""
        set(value) { savedStateHandle["message"] = value }
}

class FormActivity : AppCompatActivity() {
    private val viewModel: FormViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_form)
        Log.d("FormActivity", "onCreate: email=${viewModel.email}")
    }

    override fun onStop() {
        super.onStop()
        Log.d("FormActivity", "onStop: data uložena v SavedStateHandle")
    }
}

SavedStateHandle automaticky ukládá hodnoty do Bundle při onSaveInstanceState, které se volá před onStop. Při otáčení obrazovky nebo zabití procesu se data obnoví bez ztráty. Google doporučuje SavedStateHandle pro formuláře a koncepty namísto přímého onSaveInstanceState.

Příklad 3: lifecycleScope pro operace v onStop

Použití lifecycleScope s korutinami pro asynchronní ukládání dat při přechodu do onStop. Korutina se spouští v IO dispečeru, neblokuje hlavní vlákno.

kotlin
class NoteActivity : AppCompatActivity() {
    private val noteRepository = NoteRepository()

    override fun onStop() {
        lifecycleScope.launch(Dispatchers.IO) {
            val text = findViewById<EditText>(R.id.note_content).text.toString()
            noteRepository.saveDraft(text)
            withContext(Dispatchers.Main) {
                Log.d("NoteActivity", "Koncept uložen v onStop")
            }
        }
        super.onStop()
    }
}

Korutina lifecycleScope.launch se automaticky ruší, pokud životní cyklus Activity skončí. Použití Dispatchers.IO zaručuje, že zápis do databáze nebo souboru neblokuje návrat na Activity. Podle Google jsou korutiny v lifecycleScope preferovaným způsobem asynchronních operací v onStop.

Často kladené otázky

Jaký je rozdíl mezi onStop a onDestroy?

onStop — Activity přestává být viditelné, ale zůstává v paměti ve stavu Stopped. Systém může vrátit Activity přes onRestart. onDestroy — Activity je zničeno, paměť je uvolněna. Po onDestroy je návrat možný pouze vytvořením nové instance Activity (onCreate).

Je volání super.onStop() povinné?

Ano, povinné. super.onStop() zajišťuje správnou funkci systémových komponent: fragmentů, LoaderManager, ViewModelStore. Vynechání super.onStop() může způsobit úniky paměti a nesprávné obnovení fragmentů. Vždy volejte super.onStop() jako poslední nebo první — pořadí není kritické, ale volání je povinné.

Jak zkontrolovat, že byl onStop zavolán?

Použijte Log.d nebo Timber v každé metodě životního cyklu. Zapněte filtr logcat podle tagu vašeho Activity. Pro produkci použijte Android Vitals — Google automaticky sbírá metriky životního cyklu a zobrazuje anomálie v Play Console. K dispozici je také monitorování životního cyklu přes ProcessLifecycleOwner.

Co se stane, když v onStop dojde k výjimce?

Neošetřená výjimka v onStop způsobí Force Close aplikace. Systém nezachycuje výjimky v callbackách životního cyklu. Pokud se v onStop provádějí operace, které mohou vyhodit výjimku (práce se soubory, sítí), obalte je try-catch a zaznamenejte chybu, aniž byste přerušili provádění super.onStop().

Je třeba uvolnit Bitmap v onStop?

Ne, Bitmap v Activity bude shromážděn GC, pokud na něj nejsou odkazy. Vynucené uvolnění (recycle()) v onStop není nutné a dokonce škodlivé — pokud se Activity vrátí přes onRestart, Bitmap bude muset být znovu načten. Používejte Glide nebo Coil pro načítání obrázků — tyto knihovny automaticky spravují mezipaměť a životní cyklus.

Shrnutí

  • onStop — metoda životního cyklu Activity, volaná při úplné ztrátě viditelnosti. Activity zůstává v paměti ve stavu Stopped.
  • Po onStop jsou možné dva scénáře: onRestart (návrat na obrazovku) nebo onDestroy (zničení Activity).
  • V onStop je třeba uvolnit senzory, animace, kameru, location-listenery — vše, co není potřeba při neviditelném Activity.
  • onStop se liší od onPause stupněm viditelnosti: onPause — částečná, onStop — úplná ztráta viditelnosti.
  • onSaveInstanceState se volá před onStop — použijte jej pro uložení přechodného stavu UI.
  • Korutiny lifecycleScope s Dispatchers.IO — preferovaný způsob asynchronních operací v onStop.
  • Vždy volejte super.onStop() a obalte nebezpečné operace try-catch, abyste předešli Force Close.

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é