onRestart — metoda cyklu życia Activity w Androidzie, wywoływana przez system przed powrotem Activity ze stanu Stopped do stanu Started. onRestart sygnalizuje, że Activity, wcześniej ukryte przez inny ekran lub zminimalizowane do tła, ponownie staje się widoczne dla użytkownika. W onRestart programista aktualizuje nieaktualne dane, przeładowuje listy i przywraca stan UI, który mógł się zmienić, gdy Activity było niewidoczne. Według Google Android Vitals (2025), aplikacje używające onRestart do aktualizacji danych wykazują o 25% mniej przypadków nieprawidłowego wyświetlania informacji po powrocie na ekran. Dokumentacja Android Developers opisuje onRestart jako etap przygotowawczy przed ponownym pojawieniem się Activity na ekranie.
Najważniejsze
onRestart — metoda callback, którą Android wywołuje ściśle przed onStart, gdy Activity powraca z niewidocznego stanu Stopped z powrotem do widocznego. Ta metoda jest wyjątkowa, ponieważ jest wywoływana tylko przy ponownym wyświetleniu Activity — przy pierwszym utworzeniu instancji sekwencja zaczyna się od onCreate, pomijając onRestart. Pełny cykl: onCreate → onStart → onResume (pierwsze uruchomienie) lub onRestart → onStart → onResume (ponowne wyświetlenie).
Z punktu widzenia systemu Android, onRestart to optymalizacja, która pozwala Activity przygotować się do powrotu: zaktualizować dane z repozytorium, zsynchronizować stan UI, sprawdzić połączenie sieciowe. W przeciwieństwie do onResume, który jest wywoływany za każdym razem przy uzyskaniu fokusu (w tym przy powrocie z dialogu lub menu systemowego), onRestart uruchamia się tylko przy pełnym cyklu ukrycia-powrotu. To czyni onRestart idealnym miejscem dla „ciężkich” operacji aktualizacji, które nie są potrzebne przy częściowej utracie fokusu.
Zgodnie ze specyfikacją cyklu życia Android Activity, odstęp czasu między onStop a onRestart może wynosić od kilku sekund (użytkownik szybko się przełączył) do kilku godzin (aplikacja była w tle i użytkownik wrócił). W tym czasie dane w zdalnym źródle (API, DB) mogły się zmienić, dlatego onRestart jest naturalnym punktem do sprawdzenia aktualności.
onRestart jest wywoływany tylko przy powrocie Activity ze stanu Stopped, do którego Activity przeszło po wywołaniu onStop. Poniżej wymieniono wszystkie scenariusze prowadzące do onRestart.
Scenariusze wywołania onRestart:
Kiedy onRestart NIE jest wywoływany: przy obrocie ekranu (Activity jest niszczone i tworzone od nowa przez onCreate), przy powrocie z okna dialogowego (Activity nie przechodzi do onStop, tylko onPause → onResume), przy process death (Activity jest tworzone od nowa).
onRestart i onCreate to dwa różne podejścia do przywracania Activity. Wybór między nimi zależy od tego, czy Activity zostało całkowicie zniszczone, czy tylko ukryte.
| Cecha | onRestart | onCreate |
|---|---|---|
| Kiedy wywoływany | Activity powraca ze stanu Stopped | Activity jest tworzone po raz pierwszy lub po zniszczeniu |
| Stan zachowany | Tak — ViewModel i pola żyją | Nie — wszystko tworzone od nowa |
| Bundle | Nie przekazywany | Przekazywany (savedInstanceState) |
| Typowe działania | Aktualizacja danych, odświeżenie UI | Inicjalizacja View, subskrypcja LiveData |
| Częstotliwość wywołania | Za każdym razem przy powrocie | Raz lub po zniszczeniu |
Zasada wyboru: inicjalizację View i subskrypcję LiveData/StateFlow wykonuj w onCreate (lub onViewCreated dla Fragment). Aktualizację danych, przeładowanie list i sprawdzenie stanu — w onRestart. Jeśli dane są ładowane przez ViewModel, onRestart może po prostu wywołać metodę refresh() na ViewModel, a View zasubskrybuje zaktualizowane dane przez strumień reaktywny.
Google zaleca: nie powielaj logiki onCreate w onRestart. Wydziel w ViewModel metody refresh(), które ładują aktualne dane, i wywołuj je w onRestart. To zachowuje czystość architektury MVVM i eliminuje powielanie kodu.
onRestart — idealne miejsce dla operacji, które powinny być wykonywane przy każdym powrocie na ekran, ale nie są potrzebne przy pierwszym otwarciu. Oto typowe scenariusze:
viewModel.refreshItems() w onRestart.Czego nie robić w onRestart: nie inicjalizuj View od nowa — one żyją, ponieważ Activity nie zostało zniszczone. Nie subskrybuj LiveData ponownie — subskrypcja w onCreate żyje. Nie twórz nowych fragmentów — one już są w FragmentManager.
Najważniejszy wyjątek: onRestart nie jest wywoływany, jeśli proces aplikacji został zabity przez system. To kluczowy moment, który programiści często pomijają, polegając na onRestart do przywracania stanu.
Przy process death:
Jak się przed tym zabezpieczyć: zawsze zapisuj krytyczny stan w onSaveInstanceState(Bundle) (wywoływany przed onStop) lub używaj SavedStateHandle w ViewModel. W onCreate sprawdzaj savedInstanceState: jeśli nie jest null, przywracaj stan z Bundle, jeśli null — ładuj świeże dane.
Według Google Android Vitals, około 7% powrotów do Activity po dłuższym przebywaniu w tle następuje po process death. Oznacza to, że co 15-te Activity, które powinno wywołać onRestart, w rzeczywistości przechodzi przez onCreate. Ignorowanie tego scenariusza to jedna z głównych przyczyn błędów „pusty ekran po powrocie”.
Activity wywołuje viewModel.refreshTasks() w onRestart, aby zaktualizować listę zadań po powrocie z ekranu edycji.
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", "Otrzymano ${tasks.size} zadań")
}
}
override fun onRestart() {
super.onRestart()
Log.d("TaskList", "onRestart: aktualizacja listy zadań")
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() ładuje aktualne dane z repozytorium. LiveData automatycznie powiadamia Activity o zmianie danych — UI aktualizuje się bez dodatkowego kodu. OnRestart nie tworzy nowej subskrypcji — jest już ustanowiona w onCreate.
Activity sprawdza ważność tokena przy powrocie i przekierowuje do logowania w razie potrzeby.
class ProfileActivity : AppCompatActivity() {
private val authManager = AuthManager()
private val launcher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { Log.d("Profile", "Wrócono z ekranu logowania") }
override fun onRestart() {
super.onRestart()
if (!authManager.isTokenValid()) {
Log.d("Profile", "Token wygasł — przekierowanie do logowania")
launcher.launch(Intent(this, LoginActivity::class.java))
}
}
}
class AuthManager {
fun isTokenValid(): Boolean {
val expiry = SharedPreferencesManager().getTokenExpiry()
return System.currentTimeMillis() < expiry
}
}
Jeśli użytkownik zminimalizował aplikację na dłuższy czas i wrócił po wygaśnięciu tokena, onRestart przekieruje go na ekran logowania. Zapobiega to błędom API przy próbie wykonania zapytania z wygasłym tokenem. Zwróć uwagę: sprawdzenie w onRestart, a nie w onResume, aby uniknąć zbędnego sprawdzania przy powrocie z dialogu.
Fragment używa onRestart przez LifecycleObserver do aktualizacji danych.
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 przez LifecycleObserver")
viewModel.refreshFeed()
}
})
}
}
Zamiast nadpisywania onRestart we Fragment używany jest LifecycleObserver — bardziej elastyczne podejście, które pozwala dodawać logikę do zdarzeń cyklu życia bez dziedziczenia. ViewLifecycleOwner gwarantuje, że observer żyje w zakresie View (nie przeżywa onDestroyView).
Często zadawane pytania
onResume jest wywoływany za każdym razem, gdy Activity uzyskuje fokus — w tym przy powrocie z dialogu lub menu systemowego (Activity nie przechodziło do onStop). onRestart jest wywoływany tylko przy powrocie ze stanu Stopped, gdy Activity było całkowicie ukryte. onRestart to bardziej szczegółowe zdarzenie dla „ciężkich” aktualizacji, onResume — dla lekkich operacji (zmiana tytułu, aktualizacja czasu).
Nie, nie może. onRestart to metoda sparowana z onStop: onRestart jest wywoływany tylko po tym, jak Activity przeszło przez onStop. Jeśli Activity nie przeszło do onStop (np. otwarte jest okno dialogowe), to przy powrocie onRestart nie jest wywoływany — tylko onResume.
Naciśnij Home (przycisk domku) w emulatorze — Activity zostanie zminimalizowane, otrzyma onStop. Następnie otwórz aplikację przez Recent Apps lub launcher — Activity otrzyma onRestart → onStart → onResume. Do debugowania używaj Debug z punktami zatrzymania w onRestart lub Log.d z tagiem Activity.
Nieobsłużony wyjątek w onRestart spowoduje Force Close. System nie przechwytuje wyjątków w callbackach cyklu życia. Jeśli w onRestart wykonywane są operacje, które mogą zgłosić wyjątek (zapytanie sieciowe bez try-catch, praca z null View), należy je otoczyć try-catch.
Nie. onRestart jest wywoływany tylko dla żywych Activity, które wracają ze stanu Stopped. isFinishing() w onRestart zawsze będzie false. Sprawdzanie isFinishing() ma sens w onPause (zapisywanie danych) i onDestroy (odróżnienie odtworzenia od finish()).
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również