onStop — metoda ciclului de viață al Activity în Android, apelată de sistem când Activity nu mai este vizibilă pentru utilizator. Activity trece în starea Stopped după ce o nouă Activity o acoperă complet sau la minimizarea aplicației. În metoda onStop, dezvoltatorul este obligat să oprească animațiile, să elibereze resursele camerei și senzorilor, să salveze ciornele datelor introduse. Conform Android Vitals (Google, 2025), gestionarea corectă a onStop reduce numărul de ANR (Application Not Responding) la minimizarea aplicației cu 35%. După onStop, sistemul poate apela onRestart (revenirea pe ecran) sau onDestroy (încheierea completă). Documentația Android Developers despre ciclul de viață al Activity descrie onStop ca granița dintre starea vizibilă și cea invizibilă.
Principalele puncte
onStop — este un callback al clasei AppCompatActivity (și al predecesorului său Activity), care este apelat de sistemul de operare Android atunci când Activity încetează să mai fie complet vizibilă pentru utilizator. În acest moment, Activity este ascunsă de o altă Activity, o fereastră de dialog, lansatorul de sistem sau ecranul de blocare. Din perspectiva ciclului de viață, onStop urmează după onPause și semnalează că Activity nu mai este vizibilă pe ecran, deși obiectul Activity și starea sa rămân în memorie.
Când Activity trece în starea Stopped (oprită), își păstrează starea în memoria RAM — toate câmpurile, ierarhia View și ViewModel rămân accesibile. Acest lucru deosebește Stopped de starea distrusă (Destroyed), în care Activity este eliminată complet. System UI poate ucide procesul aplicației aflate în starea Stopped la insuficiența memoriei — acesta este așa-numitul process death. Dezvoltatorul este obligat să salveze datele critice (ciorne, poziția de derulare) în onSaveInstanceState(), care este apelat înainte de onStop, pentru a garanta restaurarea la uciderea procesului.
Conform specificației Android Compatibility Definition Document (CDD) pentru versiunea 14+, procesul în starea Stopped are prioritate redusă la uciderea de către OOM Killer — mai mică decât procesele în faza Background, dar mai mare decât procesele din cache. Potrivit statisticilor Google, 68% din cazurile de ucidere a proceselor au loc când Activity se află în starea Stopped, nu Paused.
onStop este apelat la pierderea completă a vizibilității Activity, indiferent de cauză: lansarea unei noi Activity peste cea curentă, minimizarea aplicației (apăsarea Home), blocarea ecranului, un apel primit sau deschiderea unui dialog de sistem. În toate aceste cazuri, Activity primește mai întâi onPause (pierderea parțială a focalizării), apoi onStop (pierderea completă a vizibilității).
Principalele scenarii de apelare a onStop:
Este important de înțeles că onStop nu este apelat la rotirea ecranului — în acest caz, Activity este distrusă (onPause → onStop → onDestroy) și recreată (onCreate → onStart → onResume). Excepție — flagul android:configChanges="orientation" în manifest, la care Activity nu este recreată, ci primește apelul onConfigurationChanged().
onStop ocupă un loc central în secvența ciclului de viață al Activity între starea vizibilă și cea invizibilă. Secvența completă: onCreate → onStart → onResume → (stare activă) → onPause → onStop → onDestroy (sau onRestart → onStart → onResume la revenire).
| Stare | Metodă | Vizibilitate | Interacțiune | Memorie |
|---|---|---|---|---|
| Created | onCreate | Nu | Nu | Alocată |
| Started | onStart | Parțial | Nu | Completă |
| Resumed | onResume | Completă | Da | Completă |
| Paused | onPause | Parțial | Nu | Completă |
| Stopped | onStop | Nu | Nu | Completă* |
| Destroyed | onDestroy | Nu | Nu | Eliberată |
*În starea Stopped, Activity este păstrată în memorie, dar poate fi ucisă de sistem la insuficiența resurselor. Prioritatea uciderii proceselor Stopped — penultima, mai mare doar decât procesele goale din cache.
onStop și onSaveInstanceState: Sistemul apelează onSaveInstanceState(Bundle) înainte de onStop pentru a salva starea dinamică a UI. Dezvoltatorul suprascrie această metodă pentru a salva în Bundle valorile câmpurilor de intrare, poziția RecyclerView, elementele selectate. Chiar dacă Activity nu va fi distrusă (utilizatorul doar a minimizat și s-a întors), Bundle este transmis la onCreate la schimbările de configurare. Google recomandă salvarea doar a stării tranzitorii a UI — nu a datelor din repository sau ViewModel, care trăiesc în afara Activity.
În onStop, dezvoltatorul este obligat să elibereze toate resursele care nu sunt necesare când Activity nu este vizibilă. Aceasta reduce încărcarea bateriei, procesorului și memoriei și previne ANR la revenirea pe activitate.
Ce să eliberați în onStop:
Ce să nu faceți în onStop: Nu efectuați operații lungi — salvarea datelor mari în BD, cereri de rețea, calcule complexe. onStop se execută pe firul principal și blochează revenirea pe Activity. Pentru operații lungi, utilizați WorkManager cu întârziere sau corutine în viewModelScope. Nu eliberați resursele ViewModel — ViewModel supraviețuiește onStop și va fi utilizat la revenire.
onPause și onStop diferă prin gradul de pierdere a vizibilității și volumul acțiunilor obligatorii. onPause este apelat la pierderea parțială a focalizării (de exemplu, deschiderea unei ferestre de dialog sau a meniului de sistem), onStop — la pierderea completă a vizibilității. Această diferență este importantă pentru alegerea resurselor de eliberat la fiecare etapă.
| Caracteristică | onPause | onStop |
|---|---|---|
| Grad de vizibilitate | Parțial vizibil | Complet invizibil |
| Focalizare | Pierdută | Pierdută |
| Timp de execuție | Până la 500 ms | Până la 5 s (timeout ANR) |
| Resurse de eliberat | Critice (media, cameră) | Toate invizibile (senzori, animații, location) |
| Restaurare | onResume | onRestart → onStart → onResume |
| Prioritatea procesului | Ridicată (Foreground) | Medie (Background) |
Regula generală: în onPause eliberați resursele sistemice care afectează imediat experiența utilizatorului altei aplicații (cameră, player media), în onStop — toate celelalte resurse care nu sunt necesare când Activity este ascunsă. Google recomandă în onPause salvarea datelor critice ale utilizatorului (ciorna unui e-mail, setări), deoarece onStop poate să nu apară la comutarea rapidă.
Când utilizatorul revine la Activity ascunsă, sistemul apelează onRestart → onStart → onResume. Metoda onRestart semnalează că Activity revine din starea Stopped. Aceasta este o etapă importantă pentru restaurarea UI și a resurselor care au fost eliberate în onStop.
Secvența de apeluri la revenire:
Dacă procesul aplicației a fost ucis de sistem în starea Stopped, onCreate este apelat în loc de onRestart, iar Bundle din onSaveInstanceState este transmis pentru restaurarea stării. Acest scenariu (process death) — una dintre cele mai frecvente cauze de erori în aplicațiile Android: dezvoltatorii implementează onRestart, dar uită să ia în considerare restaurarea prin onCreate după uciderea procesului.
Demonstrează dezabonarea corectă de la senzori și oprirea animației la ascunderea Activity. După revenirea pe ecran, resursele sunt restaurate în 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 revine din starea Stopped")
}
private val sensorListener = SensorEventListener { event, _ ->
Log.d("MainActivity", "Accel: x=${event.values[0]}, y=${event.values[1]}, z=${event.values[2]}")
}
}
Codul înregistrează senzorul de accelerometru și pornește o animație infinită de rotație în onStart. În onStop, senzorul este dezactivat și animația anulată — aceasta previne consumul bateriei când Activity este ascunsă. După revenirea prin onRestart → onStart, resursele sunt recreate.
Abordare modernă cu utilizarea ViewModel + SavedStateHandle. Datele formularului sunt salvate automat la onStop fără Bundle manual.
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: date salvate în SavedStateHandle")
}
}
SavedStateHandle salvează automat valorile în Bundle la onSaveInstanceState, care este apelat înainte de onStop. La rotirea ecranului sau uciderea procesului, datele sunt restaurate fără pierderi. Google recomandă SavedStateHandle pentru formulare și ciorne în loc de onSaveInstanceState direct.
Utilizarea lifecycleScope cu corutine pentru salvarea asincronă a datelor la trecerea în onStop. Corutina este lansată în dispatcherul IO, neblocând firul principal.
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", "Ciorna salvată în onStop")
}
}
super.onStop()
}
}
Corutina lifecycleScope.launch este anulată automat dacă ciclul de viață al Activity se încheie. Utilizarea Dispatchers.IO garantează că scrierea în BD sau fișier nu blochează revenirea pe Activity. Potrivit Google, corutinele în lifecycleScope sunt modalitatea preferată pentru operații asincrone în onStop.
Întrebări frecvente
onStop — Activity încetează să mai fie vizibilă, dar rămâne în memorie în starea Stopped. Sistemul poate readuce Activity prin onRestart. onDestroy — Activity este distrusă, memoria este eliberată. După onDestroy, revenirea este posibilă doar prin crearea unei noi instanțe a Activity (onCreate).
Da, obligatorie. super.onStop() asigură funcționarea corectă a componentelor sistemice: fragmente, LoaderManager, ViewModelStore. Omiterea super.onStop() poate provoca scurgeri de memorie și restaurarea incorectă a fragmentelor. Apelați întotdeauna super.onStop() ultimul sau primul — ordinea nu este critică, dar apelul este obligatoriu.
Folosiți Log.d sau Timber în fiecare metodă a ciclului de viață. Activați filtrul logcat după tagul Activity dumneavoastră. Pentru producție, utilizați Android Vitals — Google colectează automat metricile ciclului de viață și afișează anomalii în Play Console. De asemenea, este disponibilă monitorizarea ciclului de viață prin ProcessLifecycleOwner.
O excepție neprinsă în onStop provoacă Force Close al aplicației. Sistemul nu prinde excepțiile în callback-urile ciclului de viață. Dacă în onStop se execută operații care pot arunca excepții (lucrul cu fișiere, rețea), înfășurați-le în try-catch și înregistrați eroarea fără a întrerupe execuția super.onStop().
Nu, Bitmap-ul din Activity va fi colectat de GC dacă nu există referințe către el. Eliberarea forțată (recycle()) în onStop nu este necesară și chiar dăunătoare — dacă Activity revine prin onRestart, Bitmap va trebui încărcat din nou. Folosiți Glide sau Coil pentru încărcarea imaginilor — aceste biblioteci gestionează automat cache-ul și ciclul de viață.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și