onResume — este metoda ciclului de viață Android care este apelată când Activity sau Fragment iese în prim-plan și primește focalizarea intrării. În această stare ecranul este gata pentru interacțiunea cu utilizatorul: toate evenimentele tactile, apăsările de taste și gesturile sunt direcționate către această componentă. onResume este starea de lucru a Activity în care aplicația petrece cea mai mare parte a timpului. Tocmai aici se deschide camera, se pornește redarea video, se începe recunoașterea vorbirii și se înregistrează ascultătorii senzoriali care necesită acces exclusiv. Citiți mai multe despre ciclul de viață complet al Activity în articolul Activity Lifecycle.
Principalele
onResume — a treia metodă a ciclului de viață Activity, apelată după onStart, care semnalizează pregătirea ecranului pentru interacțiunea completă cu utilizatorul. În acest moment Activity se află în vârful stivei de sarcini (back stack), sistemul îi direcționează toate evenimentele de intrare, iar aplicația poate începe orice operații care necesită participarea activă a utilizatorului: apeluri video, jocuri, înregistrare audio, desenare pe Canvas.
onResume face parte din viața pe prim-plan (foreground lifetime) — intervalul dintre onResume și onPause. Aceasta este cea mai activă perioadă de lucru a Activity, când aplicația consumă maximum de resurse: procesorul pentru procesarea atingerilor, GPU-ul pentru randarea animațiilor, camera și microfonul pentru captura video. Înțelegerea acestui nivel al ciclului de viață este esențială pentru optimizarea consumului de energie — resursele deschise în onResume trebuie închise imediat în onPause.
Conform datelor Google I/O 2025, timpul mediu pe care Activity îl petrece în starea onResume într-o sesiune este de 2–5 minute pentru aplicațiile de știri și 15–30 minute pentru jocuri și mesagerie. Restul timpului Activity se află în stările onPause, onStop sau onDestroy. Aceasta înseamnă că optimizarea tocmai a codului onResume oferă cel mai mare câștig în performanță și durata de viață a bateriei.
În Activity metoda onResume este apelată de fiecare dată când ecranul primește focalizarea intrării — la prima pornire, la revenirea dintr-un alt Activity, la închiderea ferestrei de dialog, la deblocarea dispozitivului. Este o metodă fierbinte care poate fi apelată de multe ori în timpul unei sesiuni, iar implementarea sa trebuie să fie cât mai ușoară.
class CameraActivity : AppCompatActivity() {
private var cameraProvider: ProcessCameraProvider? = null
private var preview: Preview? = null
override fun onResume() {
super.onResume()
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener({
cameraProvider = cameraProviderFuture.get()
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
preview = Preview.Builder().build().also {
it.setSurfaceProvider(binding?.viewFinder?.surfaceProvider)
}
try {
cameraProvider?.unbindAll()
cameraProvider?.bindToLifecycle(
this, cameraSelector, preview
)
} catch (e: Exception) {
Log.e("Camera", "Nu s-a putut lega camera", e)
}
}, ContextCompact.getMainExecutor(this))
}
override fun onPause() {
super.onPause()
cameraProvider?.unbindAll()
preview = null
}
}
Exemplul cu CameraX demonstrează utilizarea clasică a onResume/onPause: camera este o resursă exclusivă care poate fi folosită doar de o singură aplicație la un moment dat. Legarea camerei la ciclul de viață prin bindToLifecycle închide automat camera în onPause, dar apelul explicit unbindAll garantează eliberarea imediată. Acest lucru este deosebit de important la comutarea între Activity-uri: camera trebuie eliberată înainte ca un alt Activity să încerce să o deschidă.
onResume în Fragment este apelat după ce Activity care îl conține a primit onResume. Totuși, din cauza specificului FragmentManager și ViewPager, momentul apelării onResume pentru Fragment poate fi întârziat față de Activity. De exemplu, Fragment-ul din ViewPager cu offscreenPageLimit = 1 primește onResume doar când devine pagina curentă, nu la pornirea Activity.
class VideoPlayerFragment : Fragment() {
private var exoPlayer: ExoPlayer? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
exoPlayer = ExoPlayer.Builder(requireContext()).build()
binding?.playerView?.player = exoPlayer
}
override fun onResume() {
super.onResume()
exoPlayer?.play()
if (userVisibleHint) {
startBiometricAuth()
}
}
override fun onPause() {
exoPlayer?.pause()
stopBiometricAuth()
super.onPause()
}
}
Verificarea userVisibleHint în Fragment.onResume este relevantă pentru ViewPager: Fragment poate primi onResume dar poate fi ascuns de pagina vecină (de exemplu, la tranziția animată). În astfel de cazuri, pornirea video sau a biometricii în onResume fără verificarea vizibilității va duce la un comportament neașteptat. Începând cu Fragment 1.5.0, se recomandă utilizarea FragmentTransaction.setMaxLifecycle() pentru controlul precis al ciclului de viață al fragmentelor în ViewPager2.
Dezvoltatorii confundă adesea onStart și onResume, plasând codul într-o metodă nepotrivită. Regula principală: onStart — pentru resurse care funcționează la vizibilitate; onResume — pentru resurse care necesită focalizarea intrării. Să analizăm scenarii concrete și alegerea corectă a metodei.
| Operațiune | Metodă | Justificare |
|---|---|---|
| Abonare la geolocație | onStart / onStop | GPS poate funcționa la vizibilitate parțială |
| Deschiderea camerei | onResume / onPause | Camera — resursă exclusivă |
| BroadcastReceiver | onStart / onStop | Evenimentele sistemice nu necesită focalizare |
| Redare video | onResume / onPause | Video trebuie să fie vizibil utilizatorului |
| Scanare Bluetooth | onStart / onStop | Scanarea poate continua în fundal |
| Reportofon (MediaRecorder) | onResume / onPause | Înregistrarea necesită UI activ |
| Ascultători senzoriali | onResume / onPause | Senzori pentru jocuri și gesturi |
| Actualizarea datelor | onStart | Date proaspete necesare la apariție |
Regula practică: dacă operațiunea trebuie întreruptă la apariția ferestrei de dialog — folosiți onResume/onPause. Dacă operațiunea poate continua la acoperirea parțială a ecranului — folosiți onStart/onStop. De exemplu, playerul video trebuie să pună video pe pauză la deschiderea dialogului (onPause), iar geolocația poate continua să se actualizeze (rămâne în onStart).
Resursele exclusive sunt componente ale dispozitivului care pot fi folosite doar de o singură aplicație la un moment dat. Camera, microfonul, ieșirea video (MediaProjection), adaptorul NFC în modul citire, dispozitivele USB în modul accessory — toate aceste resurse trebuie deschise în onResume și eliberate în onPause.
MediaRecorder este utilizat pentru înregistrarea audio și video. Solicitarea permisiunilor și pregătirea MediaRecorder se face în onCreate, iar pornirea înregistrării — în onResume. Dacă utilizatorul comută la o altă aplicație, onPause întrerupe înregistrarea, iar onResume o reia. Acesta este comportamentul standard pentru reportofoane și aplicații de înregistrare video.
private var mediaRecorder: MediaRecorder? = null
private var isRecording = false
override fun onResume() {
super.onResume()
if (isRecording) {
mediaRecorder?.resume()
}
}
override fun onPause() {
if (isRecording) {
mediaRecorder?.pause()
}
super.onPause()
}
Autentificarea biometrică (BiometricPrompt) trebuie apelată doar când Activity se află în onResume. Dacă o apelați în onCreate sau onStart, dialogul biometric poate apărea înainte ca Activity să termine inițializarea, ceea ce va duce la procesarea incorectă a rezultatului. Apelarea în onResume garantează că fereastra biometrică va fi afișată în contextul corect.
Să analizăm trei pattern-uri verificate de lucru cu onResume care sunt aplicate în proiecte comerciale: resetarea timerului de inactivitate, actualizarea datelor vizibile și integrarea cu Jetpack Navigation.
În aplicațiile cu date confidențiale (bancare, fișe medicale) onResume este folosit pentru resetarea timerului de ieșire automată. Dacă utilizatorul interacționează activ cu aplicația, onResume este apelat la fiecare tranziție între ecrane, iar timerul se resetează. Dacă utilizatorul a minimizat aplicația, onPause oprește timerul, iar onResume la revenire fie îl resetează, fie solicită reautentificarea.
Lista care trebuie să afișeze date actuale la fiecare revenire pe ecran este actualizată în onResume. De exemplu, dacă utilizatorul a creat o înregistrare nouă într-un alt Activity și s-a întors, onResume reîncarcă lista din baza de date locală sau din cache-ul ViewModel. Aceasta asigură consistența datelor fără apelarea manuală a notifyDataSetChanged.
override fun onResume() {
super.onResume()
// ActivityResultLauncher a returnat rezultatul — actualizăm lista
viewModel.refreshList()
// Resetarea timerului de inactivitate
inactivityTimer.reset()
}
În Jetpack Navigation onResume al fragmentului este apelat la fiecare revenire la acesta prin navigarea înapoi. Această proprietate este folosită pentru resetarea stării UI: ascunderea tastaturii, curățarea câmpurilor de căutare, actualizarea titlului barei de instrumente. OnBackPressedCallback în combinație cu onResume oferă control complet asupra navigării fără duplicarea codului.
Întrebări frecvente
onStart — ecranul este vizibil. onResume — ecranul este activ și gata pentru interacțiune. Imaginați-vă: vă uitați la televizor (onStart), dar luați telecomanda în mână (onResume). Televizorul este mereu vizibil, dar interacțiunea începe doar cu telecomanda. Dacă cineva acoperă televizorul cu o perdea — ecranul încetează să mai fie vizibil (onStop). Dacă vi se ia telecomanda — interacțiunea încetează (onPause), dar televizorul este încă vizibil.
onResume este apelat de fiecare dată când Activity primește focalizarea intrării. Numărul minim — o dată (la pornire). Maximul depinde de scenariile de utilizare: comutarea între ecrane, deschiderea dialogurilor, blocarea și deblocarea rapidă a dispozitivului — fiecare astfel de scenariu apelează onResume la revenirea pe ecran.
Camera — resursă exclusivă disponibilă doar pentru o singură aplicație la un moment dat. Dacă deschideți camera în onCreate sau onStart, aceasta va rămâne blocată pentru alte aplicații chiar și când aplicația dvs. este inactivă. onResume garantează că camera este deschisă doar când Activity este în prim-plan, iar onPause o închide imediat. Acesta este standardul dezvoltării Android, consacrat în documentația CameraX și Camera2 API.
Da, onResume poate să nu aibă loc dacă Activity este acoperit de un alt Activity imediat după apariție. De exemplu, Activity A lansează Activity B în metoda onCreate sau onStart. În acest caz A primește onStart → onPause → onStop, sărind peste onResume. Sistemul nu apelează onResume pentru că Activity A nu a primit niciodată focalizarea intrării.
În onResume nu trebuie executate operații sincrone lungi: încărcarea datelor mari din rețea, interogări SQL complexe, procesarea imaginilor. Metoda onResume rulează în firul UI și orice blocare mai lungă de 100–200 ms duce la întârzierea răspunsului interfeței. Toate operațiile grele trebuie să fie asincrone — prin corutine, RxJava sau WorkManager. De asemenea, nu se recomandă apelarea finish() în onResume fără verificare — aceasta poate duce la o buclă infinită de recreare.
Concluzii
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