onRestart — istota, przywracanie Activity w cyklu życia

Autor: IT Sectr Opublikowano: 2026-03-04 Czas czytania: 8 min

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 jest wywoływany przy powrocie Activity ze stanu Stopped, przed onStart i onResume.
  • onRestart nie jest wywoływany przy pierwszym utworzeniu Activity — tylko przy ponownym wyświetleniu po ukryciu.
  • Głównym zadaniem onRestart jest aktualizacja danych, które mogły się zmienić, gdy Activity było niewidoczne.
  • onRestart nie jest wywoływany przy process death — w tym przypadku Activity jest tworzone od nowa przez onCreate.
  • Prawidłowe użycie onRestart poprawia doświadczenie użytkownika podczas wielozadaniowości i przełączania między aplikacjami.

onRestart — istota metody w cyklu życia Androida

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.

Kiedy wywoływany jest onRestart: warunki i kolejność

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:

  • Powrót z innego Activity — użytkownik otworzył nowe Activity (np. kliknął powiadomienie), a następnie wrócił (nacisnął „Wstecz”). Stos: MainActivity.onPause → MainActivity.onStop → SecondActivity jest tworzone → użytkownik naciska „Wstecz” → SecondActivity.onPause → SecondActivity.onStop → SecondActivity.onDestroy → MainActivity.onRestart → MainActivity.onStart → MainActivity.onResume.
  • Powrót z minimalizacji — użytkownik zminimalizował aplikację (Home) i po pewnym czasie wrócił. CurrentActivity.onPause → CurrentActivity.onStop → (aplikacja w tle) → użytkownik wraca → CurrentActivity.onRestart → CurrentActivity.onStart → CurrentActivity.onResume.
  • Powrót z ekranu blokady — ekran blokady zakrywa Activity; po odblokowaniu Activity otrzymuje onRestart, jeśli minął znaczny czas (ponad 5 sekund).
  • Powrót z aplikacji uruchomionej przez Intent — aparat, galeria, przeglądarka — dowolna aplikacja zewnętrzna uruchomiona przez startActivityForResult() lub ActivityResultLauncher.

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).

Różnica między onRestart a onCreate: co wybrać

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.

CechaonRestartonCreate
Kiedy wywoływanyActivity powraca ze stanu StoppedActivity jest tworzone po raz pierwszy lub po zniszczeniu
Stan zachowanyTak — ViewModel i pola żyjąNie — wszystko tworzone od nowa
BundleNie przekazywanyPrzekazywany (savedInstanceState)
Typowe działaniaAktualizacja danych, odświeżenie UIInicjalizacja View, subskrypcja LiveData
Częstotliwość wywołaniaZa każdym razem przy powrocieRaz 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.

Scenariusze użycia onRestart: aktualizacja danych i UI

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:

  • Aktualizacja listy z DB lub API — użytkownik przeszedł do innego Activity, tam zmienił dane, wrócił — lista powinna być aktualna. Wywołaj viewModel.refreshItems() w onRestart.
  • Sprawdzenie autoryzacji — jeśli Activity było ukryte przez dłuższy czas, token dostępu mógł wygasnąć. onRestart to punkt do sprawdzenia ważności tokena i przekierowania na ekran logowania.
  • Synchronizacja stanu UI — przełączanie motywów, zmiana języka, aktualizacja ustawień — zmiany powinny zostać zastosowane po powrocie na ekran.
  • Przeładowanie multimediów — jeśli Activity wyświetla treści, które mogły się zmienić (kanał wiadomości, kurs walut, pogoda), zaktualizuj dane w onRestart.
  • Sprawdzenie połączenia sieciowego — przy powrocie z trybu offline Activity powinno sprawdzić dostępność sieci i przełączyć UI.
  • Przywrócenie animacji — animacje zwolnione w onStop uruchom ponownie w onRestart przed onStart.

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.

onRestart a process death: ważny wyjątek

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:

  • Aplikacja była w tle, Android zabił proces, aby zwolnić pamięć.
  • Użytkownik wraca — system uruchamia nowy proces.
  • Activity jest tworzone od nowa: onCreate(Bundle) → onStart → onResume.
  • onRestart NIE jest wywoływany — dla systemu to nowa instancja Activity.

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”.

Przykłady kodu z onRestart w Kotlin

Przykład 1: onRestart z aktualizacją listy przez ViewModel

Activity wywołuje viewModel.refreshTasks() w onRestart, aby zaktualizować listę zadań po powrocie z ekranu edycji.

kotlin
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.

Przykład 2: onRestart ze sprawdzeniem autoryzacji

Activity sprawdza ważność tokena przy powrocie i przekierowuje do logowania w razie potrzeby.

kotlin
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.

Przykład 3: onRestart we Fragment z ViewLifecycleOwner

Fragment używa onRestart przez LifecycleObserver do aktualizacji danych.

kotlin
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

Czym onRestart różni się od onResume?

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).

Czy onRestart może być wywołany bez onStop?

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.

Jak symulować onRestart w emulatorze?

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.

Co się stanie, jeśli w onRestart zostanie zgłoszony wyjątek?

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.

Czy trzeba sprawdzać isFinishing() w onRestart?

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

  • onRestart — metoda cyklu życia wywoływana przy powrocie Activity ze stanu Stopped, przed onStart i onResume.
  • onRestart NIE jest wywoływany przy pierwszym utworzeniu Activity — tylko przy ponownym wyświetleniu po całkowitym ukryciu.
  • Głównym przeznaczeniem onRestart jest aktualizacja nieaktualnych danych i sprawdzenie stanu (token, sieć, ustawienia).
  • onRestart nie jest wywoływany przy process death — używaj onCreate z Bundle do przywracania po zabiciu procesu.
  • Nie powielaj logiki onCreate w onRestart: inicjalizację wykonuj w onCreate, aktualizację — w onRestart.
  • Dla Fragment używaj LifecycleObserver na viewLifecycleOwner zamiast nadpisywania onRestart.
  • Poprawna implementacja onRestart poprawia UX przy wielozadaniowości i zapobiega wyświetlaniu nieaktualnych danych.

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.

Omów projekt

Przeczytaj również