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 — 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.
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:
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 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).
| Stav | Metoda | Viditelnost | Interakce | Paměť |
|---|---|---|---|---|
| Created | onCreate | Ne | Ne | Alokována |
| Started | onStart | Částečná | Ne | Plná |
| Resumed | onResume | Plná | Ano | Plná |
| Paused | onPause | Částečná | Ne | Plná |
| Stopped | onStop | Ne | Ne | Plná* |
| Destroyed | onDestroy | Ne | Ne | Uvolně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.
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:
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.
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.
| Charakteristika | onPause | onStop |
|---|---|---|
| Stupeň viditelnosti | Částečně viditelné | Zcela neviditelné |
| Fokus | Ztracen | Ztracen |
| Doba provádění | Do 500 ms | Do 5 s (ANR timeout) |
| Prostředky k uvolnění | Kritické (média, kamera) | Všechny neviditelné (senzory, animace, location) |
| Obnova | onResume | onRestart → onStart → onResume |
| Priorita procesu | Vysoká (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.
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:
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.
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.
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í.
Moderní přístup s využitím ViewModel + SavedStateHandle. Data formuláře se automaticky ukládají při onStop bez ručního Bundle.
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.
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.
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
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).
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é.
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.
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().
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í
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é