onStop — метод животног циклуса Activity у Android-у, који позива систем када Activity престане да буде видљива кориснику. Activity прелази у стање Stopped након што је нова Activity потпуно прекрије или приликом минимизирања апликације. У методи onStop програмер је дужан да заустави анимације, ослободи ресурсе камере и сензора, сачува нацрте унетих података. Према Android Vitals (Google, 2025), коректна обрада onStop смањује број ANR (Application Not Responding) при минимизирању апликације за 35%. Након onStop систем може позвати onRestart (повратак на екран) или onDestroy (потпуни завршетак). Документација Android Developers о животном циклусу Activity описује onStop као границу између видљивог и невидљивог стања.
Главне тачке
onStop — је callback метода класе AppCompatActivity (и њеног претходника Activity), коју позива оперативни систем Android када Activity престане да буде потпуно видљива кориснику. У том тренутку Activity је скривена другим Activity, дијалог прозором, системским ланчером или екраном закључавања. Са становишта животног циклуса, onStop следи након onPause и сигнализира да Activity више није видљива на екрану, иако сам објекат Activity и његово стање остају у меморији.
Када Activity пређе у стање Stopped (заустављено), она задржава своје стање у RAM меморији — сва поља, View хијерархија и ViewModel остају доступни. Ово разликује Stopped од уништеног (Destroyed) стања, где се Activity потпуно уклања. System UI може убити процес апликације која се налази у стању Stopped при недостатку меморије — то је такозвани process death. Програмер је дужан да сачува критичне податке (нацрте, позицију скроловања) у onSaveInstanceState(), који се позива пре onStop, како би гарантовао опоравак при убијању процеса.
Према спецификацији Android Compatibility Definition Document (CDD) за верзију 14+, процес у стању Stopped има нижи приоритет при убијању од стране OOM Killer-а — нижи од процеса у фази Background, али виши од кешираних процеса. Према Google статистици, 68% случајева убијања процеса дешава се када је Activity у стању Stopped, а не Paused.
onStop се позива при потпуном губитку видљивости Activity, без обзира на узрок: покретање нове Activity изнад тренутне, минимизирање апликације (притиском Home), закључавање екрана, долазни позив или отварање системског дијалога. У свим овим случајевима Activity прво добија onPause (делимични губитак фокуса), а затим onStop (потпуни губитак видљивости).
Основни сценарији позивања onStop:
Важно је разумети да се onStop не позива при ротацији екрана — у овом случају Activity се уништава (onPause → onStop → onDestroy) и поново креира (onCreate → onStart → onResume). Изузетак — флаг android:configChanges="orientation" у манифесту, при којем се Activity не рекреира, већ добија позив onConfigurationChanged().
onStop заузима централно место у секвенци животног циклуса Activity између видљивог и невидљивог стања. Потпуна секвенца: onCreate → onStart → onResume → (активно стање) → onPause → onStop → onDestroy (или onRestart → onStart → onResume при повратку).
| Стање | Метод | Видљивост | Интеракција | Меморија |
|---|---|---|---|---|
| Created | onCreate | Не | Не | Алоцирана |
| Started | onStart | Делимично | Не | Пуна |
| Resumed | onResume | Пуна | Да | Пуна |
| Paused | onPause | Делимично | Не | Пуна |
| Stopped | onStop | Не | Не | Пуна* |
| Destroyed | onDestroy | Не | Не | Ослобођена |
*У стању Stopped Activity се чува у меморији, али може бити убијена од стране система при недостатку ресурса. Приоритет убијања Stopped процеса — претпоследњи, виши само од празних кешираних процеса.
onStop и onSaveInstanceState: Систем позива onSaveInstanceState(Bundle) пре onStop за чување динамичког стања UI. Програмер преоптерећује овај метод да сачува у Bundle вредности поља за унос, позицију RecyclerView, изабране елементе. Чак и ако Activity не буде уништена (корисник је једноставно минимизирао и вратио се), Bundle се прослеђује у onCreate при конфигурационим променама. Google препоручује чување само пролазног UI стања — не података репозиторијума или ViewModel-а, који живе ван Activity.
У onStop програмер је дужан да ослободи све ресурсе који нису потребни када Activity није видљива. То смањује оптерећење батерије, процесора и меморије, а такође спречава ANR при повратку на активност.
Шта ослободити у onStop:
Шта не радити у onStop: Не обављајте дуготрајне операције — чување великих података у бази, мрежне захтеве, сложена израчунавања. onStop се извршава на главној нити и блокира повратак на Activity. За дуготрајне операције користите WorkManager са кашњењем или корутине у viewModelScope. Немојте ослобађати ViewModel ресурсе — ViewModel преживљава onStop и биће коришћен при повратку.
onPause и onStop се разликују по степену губитка видљивости и обиму обавезних радњи. onPause се позива при делимичном губитку фокуса (на пример, отварање дијалог прозора или системског менија), onStop — при потпуном губитку видљивости. Ова разлика је важна за избор које ресурсе ослободити у свакој фази.
| Карактеристика | onPause | onStop |
|---|---|---|
| Степен видљивости | Делимично видљиво | Потпуно невидљиво |
| Фокус | Изгубљен | Изгубљен |
| Време извршења | До 500 ms | До 5 s (ANR timeout) |
| Ресурси за ослобађање | Критични (медија, камера) | Сви невидљиви (сензори, анимације, location) |
| Опоравак | onResume | onRestart → onStart → onResume |
| Приоритет процеса | Висок (Foreground) | Средњи (Background) |
Опште правило: у onPause ослобађајте системске ресурсе који одмах утичу на корисничко искуство друге апликације (камера, медија плејер), у onStop — све остале ресурсе који нису потребни када је Activity скривена. Google препоручује у onPause чување критичних корисничких података (нацрт имејла, подешавања), јер onStop можда неће наступити при брзом пребацивању.
Када се корисник врати на скривену Activity, систем позива onRestart → onStart → onResume. Метод onRestart сигнализира да се Activity враћа из Stopped стања. Ово је важна фаза за обнављање UI и ресурса који су ослобођени у onStop.
Секвенца позива при повратку:
Ако је процес апликације убијен од стране система у стању Stopped, onCreate се позива уместо onRestart, а Bundle из onSaveInstanceState се прослеђује за обнављање стања. Овај сценарио (process death) — један од најчешћих узрока грешака у Android апликацијама: програмери имплементирају onRestart, али заборављају да узму у обзир обнављање путем onCreate након убијања процеса.
Приказује коректно одјављивање са сензора и заустављање анимације при скривању Activity. Након повратка на екран, ресурси се обнављају у 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 се враћа из Stopped стања")
}
private val sensorListener = SensorEventListener { event, _ ->
Log.d("MainActivity", "Accel: x=${event.values[0]}, y=${event.values[1]}, z=${event.values[2]}")
}
}
Код региструје сензор акцелерометра и покреће бесконачну анимацију ротације у onStart. У onStop сензор се искључује и анимација се отказује — ово спречава трошење батерије када је Activity скривена. Након повратка кроз onRestart → onStart, ресурси се поново креирају.
Модерни приступ са коришћењем ViewModel + SavedStateHandle. Подаци форме се аутоматски чувају при onStop без ручног 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: подаци сачувани у SavedStateHandle")
}
}
SavedStateHandle аутоматски чува вредности у Bundle при onSaveInstanceState, који се позива пре onStop. При ротацији екрана или убијању процеса, подаци се обнављају без губитка. Google препоручује SavedStateHandle за форме и нацрте уместо директног onSaveInstanceState.
Коришћење lifecycleScope са корутинама за асинхроно чување података при преласку у onStop. Корутина се покреће у IO dispatcher-у, не блокирајући главну нит.
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", "Нацрт сачуван у onStop")
}
}
super.onStop()
}
}
Корутина lifecycleScope.launch се аутоматски отказује ако се животни циклус Activity заврши. Коришћење Dispatchers.IO гарантује да упис у базу или датотеку не блокира повратак на Activity. Према Google-у, корутине у lifecycleScope су пожељан начин за асинхроне операције у onStop.
Често постављана питања
onStop — Activity престаје да буде видљива, али остаје у меморији у стању Stopped. Систем може вратити Activity путем onRestart. onDestroy — Activity се уништава, меморија се ослобађа. Након onDestroy повратак је могућ само кроз креирање нове инстанце Activity (onCreate).
Да, обавезно. super.onStop() обезбеђује коректно функционисање системских компоненти: фрагмената, LoaderManager-а, ViewModelStore-а. Пропуштање super.onStop() може изазвати цурење меморије и некоректан опоравак фрагмената. Увек позивајте super.onStop() последњи или први — редослед није критичан, али позив је обавезан.
Користите Log.d или Timber у свакој методи животног циклуса. Укључите филтер logcat по tag-у ваше Activity. За продукцију користите Android Vitals — Google аутоматски прикупља метрике животног циклуса и приказује аномалије у Play Console. Такође је доступан мониторинг животног циклуса путем ProcessLifecycleOwner.
Неухваћени изузетак у onStop изазива Force Close апликације. Систем не хвата изузетке у callback-има животног циклуса. Ако се у onStop извршавају операције које могу бацити изузетак (рад са датотекама, мрежом), обавите их у try-catch и забележите грешку, не прекидајући извршење super.onStop().
Не, Bitmap у Activity ће бити сакупљен од стране GC ако нема референци на њега. Присилно ослобађање (recycle()) у onStop није потребно и чак је штетно — ако се Activity врати путем onRestart, Bitmap ће морати поново да се учита. Користите Glide или Coil за учитавање слика — ове библиотеке аутоматски управљају кешом и животним циклусом.
Резиме
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође