onRestart — metodă a ciclului de viață Activity în Android, apelată de sistem înainte de întoarcerea Activity din starea Stopped în starea Started. onRestart semnalează că Activity, anterior ascunsă de un alt ecran sau minimizată în fundal, devine din nou vizibilă pentru utilizator. În onRestart dezvoltatorul actualizează datele învechite, reîncarcă listele și restaurează starea UI care s-ar fi putut modifica cât timp Activity era invizibilă. Conform Google Android Vitals (2025), aplicațiile care folosesc onRestart pentru actualizarea datelor arată cu 25% mai puține cazuri de afișare incorectă a informațiilor la revenirea pe ecran. Documentația Android Developers descrie onRestart ca etapă pregătitoare înainte ca Activity să reapară pe ecran.
Principalele puncte
onRestart — metoda callback pe care Android o apelează strict înainte de onStart, când Activity revine din starea invizibilă Stopped înapoi în starea vizibilă. Această metodă este unică prin faptul că este apelată doar la afișarea repetată a Activity — la prima creare a instanței secvența începe cu onCreate, sărind peste onRestart. Ciclul complet: onCreate → onStart → onResume (prima lansare) sau onRestart → onStart → onResume (afișare repetată).
Din punctul de vedere al sistemului Android, onRestart este o optimizare care permite Activity să se pregătească pentru revenire: să actualizeze datele din repository, să sincronizeze starea UI, să verifice conexiunea la rețea. Spre deosebire de onResume, care este apelat de fiecare dată când primește focus (inclusiv la revenirea dintr-un dialog sau meniul de sistem), onRestart se activează doar la ciclul complet de ascundere-revenire. Acest lucru face din onRestart locul ideal pentru operații „grele” de actualizare, care nu sunt necesare la pierderea parțială a focusului.
Conform specificației ciclului de viață Android Activity, intervalul de timp între onStop și onRestart poate varia de la câteva secunde (utilizatorul a comutat rapid) până la câteva ore (aplicația a fost în fundal și utilizatorul s-a întors). În acest timp datele din sursa la distanță (API, DB) s-ar fi putut modifica, de aceea onRestart este punctul natural pentru verificarea actualității.
onRestart este apelat doar la revenirea Activity din starea Stopped, în care Activity a intrat după apelul onStop. Mai jos sunt enumerate toate scenariile care duc la onRestart.
Scenarii de apelare onRestart:
Când onRestart NU este apelat: la rotirea ecranului (Activity este distrus și creat din nou prin onCreate), la revenirea dintr-o fereastră de dialog (Activity nu intră în onStop, doar onPause → onResume), la process death (Activity este creat din nou).
onRestart și onCreate sunt două abordări diferite pentru restaurarea Activity. Alegerea între ele depinde de faptul dacă Activity a fost complet distrus sau doar ascuns.
| Caracteristică | onRestart | onCreate |
|---|---|---|
| Când este apelat | Activity revine din Stopped | Activity este creat pentru prima dată sau după distrugere |
| Stare salvată | Da — ViewModel și câmpurile sunt vii | Nu — totul este creat din nou |
| Bundle | Nu este transmis | Este transmis (savedInstanceState) |
| Acțiuni tipice | Actualizare date, reîmprospătare UI | Inițializare View, abonare LiveData |
| Frecvența apelării | De fiecare dată la revenire | O dată sau după distrugere |
Regula de alegere: inițializarea View și abonarea la LiveData/StateFlow faceți în onCreate (sau onViewCreated pentru Fragment). Actualizarea datelor, reîncărcarea listelor și verificarea stării — în onRestart. Dacă datele sunt încărcate prin ViewModel, onRestart poate apela pur și simplu metoda refresh() pe ViewModel, iar View se va abona la datele actualizate prin fluxul reactiv.
Google recomandă: nu duplicați logica onCreate în onRestart. Separați în ViewModel metodele refresh() care încarcă datele actuale și apelați-le în onRestart. Aceasta păstrează puritatea arhitecturii MVVM și elimină duplicarea codului.
onRestart — locul ideal pentru operațiile care trebuie executate la fiecare revenire pe ecran, dar nu sunt necesare la prima deschidere. Iată scenariile tipice:
viewModel.refreshItems() în onRestart.Ce să nu faceți în onRestart: nu inițializați View din nou — ele sunt vii deoarece Activity nu a fost distrus. Nu vă abonați din nou la LiveData — abonarea în onCreate este vie. Nu creați fragmente noi — ele sunt deja în FragmentManager.
Cea mai importantă excepție: onRestart nu este apelat dacă procesul aplicației a fost ucis de sistem. Acesta este momentul cheie pe care dezvoltatorii îl pierd adesea, bazându-se pe onRestart pentru restaurarea stării.
La process death:
Cum să vă protejați: salvați întotdeauna starea critică în onSaveInstanceState(Bundle) (apelat înainte de onStop) sau folosiți SavedStateHandle în ViewModel. În onCreate verificați savedInstanceState: dacă nu este null, restaurați starea din Bundle, dacă este null — încărcați date proaspete.
Conform Google Android Vitals, aproximativ 7% dintre revenirile la Activity după o ședere îndelungată în fundal au loc după process death. Aceasta înseamnă că fiecare al 15-lea Activity care ar fi trebuit să apeleze onRestart trece de fapt prin onCreate. Ignorarea acestui scenariu este una dintre principalele cauze ale bugurilor „ecran gol după revenire”.
Activity apelează viewModel.refreshTasks() în onRestart pentru a actualiza lista de sarcini după revenirea de pe ecranul de editare.
class TaskListActivity : AppCompatActivity() {
private val viewModel: TaskViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_task_list)
viewModel.tasks.observe(this) { tasks ->
Log.d("TaskList", "Au fost primite ${tasks.size} sarcini")
}
}
override fun onRestart() {
super.onRestart()
Log.d("TaskList", "onRestart: actualizarea listei de sarcini")
viewModel.refreshTasks()
}
}
class TaskViewModel : ViewModel() {
private val _tasks = MutableLiveData<List<Task>>()
val tasks: LiveData<List<Task>> get() = _tasks
fun refreshTasks() {
viewModelScope.launch {
_tasks.value = TaskRepository().getAllTasks()
}
}
}
ViewModel.refreshTasks() încarcă datele actuale din repository. LiveData notifică automat Activity despre modificarea datelor — UI se actualizează fără cod suplimentar. OnRestart nu creează o nouă abonare — aceasta este deja stabilită în onCreate.
Activity verifică valabilitatea tokenului la revenire și redirecționează către login dacă este necesar.
class ProfileActivity : AppCompatActivity() {
private val authManager = AuthManager()
private val launcher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { Log.d("Profile", "Ne-am întors de pe ecranul de login") }
override fun onRestart() {
super.onRestart()
if (!authManager.isTokenValid()) {
Log.d("Profile", "Tokenul a expirat — redirecționare la login")
launcher.launch(Intent(this, LoginActivity::class.java))
}
}
}
class AuthManager {
fun isTokenValid(): Boolean {
val expiry = SharedPreferencesManager().getTokenExpiry()
return System.currentTimeMillis() < expiry
}
}
Dacă utilizatorul a minimizat aplicația pentru o perioadă îndelungată și s-a întors după expirarea tokenului, onRestart îl va redirecționa către ecranul de login. Aceasta previne erorile API la încercarea de a efectua o cerere cu un token expirat. Atenție: verificarea în onRestart, nu în onResume, pentru a evita verificarea inutilă la revenirea dintr-un dialog.
Fragment folosește onRestart prin LifecycleObserver pentru actualizarea datelor.
class FeedFragment : Fragment() {
private val viewModel: FeedViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycle.addObserver(object : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_RESTART)
fun onRestart() {
Log.d("FeedFragment", "onRestart prin LifecycleObserver")
viewModel.refreshFeed()
}
})
}
}
În loc să suprascrieți onRestart în Fragment, se folosește LifecycleObserver — o abordare mai flexibilă care permite adăugarea logicii la evenimentele ciclului de viață fără moștenire. ViewLifecycleOwner garantează că observerul trăiește în domeniul View (nu supraviețuiește lui onDestroyView).
Întrebări frecvente
onResume este apelat de fiecare dată când Activity primește focus — inclusiv la revenirea dintr-un dialog sau meniul de sistem (Activity nu a intrat în onStop). onRestart este apelat doar la revenirea din starea Stopped, când Activity a fost complet ascunsă. onRestart este un eveniment mai restrâns pentru actualizări „grele”, onResume — pentru operații ușoare (schimbarea titlului, actualizarea orei).
Nu, nu poate. onRestart este metoda pereche a lui onStop: onRestart este apelat doar după ce Activity a trecut prin onStop. Dacă Activity nu a intrat în onStop (de exemplu, este deschisă o fereastră de dialog), atunci la revenire onRestart nu este apelat — doar onResume.
Apăsați Home (butonul căsuță) în emulator — Activity se va minimiza, va primi onStop. Apoi deschideți aplicația prin Recent Apps sau lansator — Activity va primi onRestart → onStart → onResume. Pentru depanare folosiți Debug cu puncte de oprire în onRestart sau Log.d cu tag-ul Activity.
O excepție neprinsă în onRestart va cauza Force Close. Sistemul nu prinde excepții în callback-urile ciclului de viață. Dacă în onRestart se execută operații care pot arunca excepții (cerere de rețea fără try-catch, lucrul cu View null), înfășurați-le în try-catch.
Nu. onRestart este apelat doar pentru Activity vii care revin din starea Stopped. isFinishing() în onRestart va fi întotdeauna false. Verificarea isFinishing() are sens în onPause (salvarea datelor) și onDestroy (diferențierea recreerii de finish()).
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