onRestart — restoring Activity in the lifecycle

Author: IT Sectr Published: 2026-03-04 Reading time: 8 min

onRestart — a method of the Android Activity lifecycle, called by the system before the Activity returns from the Stopped state to the Started state. onRestart signals that an Activity, previously hidden by another screen or minimized to the background, is becoming visible to the user again. In onRestart, the developer updates stale data, reloads lists, and restores the UI state that may have changed while the Activity was invisible. According to Google Android Vitals (2025), apps that use onRestart to update data show 25% fewer cases of incorrect information display when returning to the screen. Android Developers Documentation describes onRestart as a preparatory step before the Activity appears on screen again.

Key Takeaways

  • onRestart is called when an Activity returns from the Stopped state, before onStart and onResume.
  • onRestart is not called when the Activity is first created — only when it is shown again after being hidden.
  • The main purpose of onRestart is to update data that may have changed while the Activity was invisible.
  • onRestart is not called during process death — in this case, the Activity is recreated via onCreate.
  • Proper use of onRestart improves the user experience during multitasking and switching between apps.

onRestart — the essence of the method in the Android lifecycle

onRestart — a callback method that Android calls strictly before onStart when an Activity returns from the invisible Stopped state back to being visible. This method is unique in that it is only called when the Activity is shown again — during the first creation of the instance, the sequence starts with onCreate, skipping onRestart. The full cycle: onCreate → onStart → onResume (first launch) or onRestart → onStart → onResume (subsequent display).

From the Android system’s perspective, onRestart is an optimization that allows the Activity to prepare for its return: update data from the repository, synchronize UI state, check network connectivity. Unlike onResume, which is called every time the Activity gains focus (including when returning from a dialog or system menu), onRestart is triggered only during a full hide-and-return cycle. This makes onRestart the ideal place for “heavy” update operations that are not needed during partial focus loss.

According to the Android Activity lifecycle specification, the time interval between onStop and onRestart can range from a few seconds (user quickly switched) to several hours (the app was in the background and the user returned). During this time, data in a remote source (API, DB) could have changed, so onRestart is a natural point for checking freshness.

When onRestart is called: conditions and sequence

onRestart is only called when an Activity returns from the Stopped state, which the Activity entered after onStop was called. Below are all the scenarios that lead to onRestart.

onRestart invocation scenarios:

  • Returning from another Activity — the user opened a new Activity (e.g., tapped a notification) and then navigated back (pressed “Back”). Stack: MainActivity.onPause → MainActivity.onStop → SecondActivity is created → user presses “Back” → SecondActivity.onPause → SecondActivity.onStop → SecondActivity.onDestroy → MainActivity.onRestart → MainActivity.onStart → MainActivity.onResume.
  • Returning from minimizing — the user minimized the app (Home) and after some time returned. CurrentActivity.onPause → CurrentActivity.onStop → (app in background) → user returns → CurrentActivity.onRestart → CurrentActivity.onStart → CurrentActivity.onResume.
  • Returning from the lock screen — the lock screen overlays the Activity; after unlocking, the Activity receives onRestart if a significant amount of time has passed (more than 5 seconds).
  • Returning from an app launched via Intent — camera, gallery, browser — any third-party app launched via startActivityForResult() or ActivityResultLauncher.

When onRestart is NOT called: during screen rotation (the Activity is destroyed and recreated via onCreate), when returning from a dialog box (the Activity does not go into onStop, only onPause → onResume), during process death (the Activity is recreated).

onRestart vs onCreate: which one to choose

onRestart and onCreate are two different approaches to restoring an Activity. The choice between them depends on whether the Activity was completely destroyed or simply hidden.

CharacteristiconRestartonCreate
When it is calledActivity returns from StoppedActivity is created for the first time or after being destroyed
State preservedYes — ViewModel and fields are aliveNo — everything is created anew
BundleNot passedPassed (savedInstanceState)
Typical actionsData update, UI refreshView initialization, LiveData subscription
Call frequencyEvery time upon returnOnce or after destruction

Selection rule: do View initialization and LiveData/StateFlow subscription in onCreate (or onViewCreated for Fragment). Data updates, list reloading, and state checks — in onRestart. If data is loaded via ViewModel, onRestart can simply call the refresh() method on the ViewModel, and the View will subscribe to the updated data through a reactive stream.

Google recommends: do not duplicate onCreate logic in onRestart. Extract refresh() methods in ViewModel that load current data, and call them in onRestart. This preserves clean MVVM architecture and eliminates code duplication.

onRestart use cases: updating data and UI

onRestart is the ideal place for operations that should be performed every time the screen is returned to, but are not needed on first open. Here are typical scenarios:

  • Updating a list from DB or API — the user went to another Activity, changed data there, came back — the list should be up to date. Call viewModel.refreshItems() in onRestart.
  • Authorization check — if the Activity was hidden for a long time, the access token may have expired. onRestart is the point to check token validity and redirect to the login screen.
  • UI state synchronization — theme switching, language changes, settings updates — changes should apply when returning to the screen.
  • Media reload — if the Activity displays content that may have changed (news feed, currency rates, weather), update the data in onRestart.
  • Network connectivity check — when returning from offline mode, the Activity should check network availability and switch the UI.
  • Animation restoration — animations released in onStop should be restarted in onRestart before onStart.

What NOT to do in onRestart: do not reinitialize Views — they are alive because the Activity was not destroyed. Do not resubscribe to LiveData — the subscription in onCreate is still alive. Do not create new Fragments — they are already in the FragmentManager.

onRestart and process death: an important exception

The most important exception: onRestart is not called if the app process was killed by the system. This is a key point that developers often miss when relying on onRestart for state restoration.

During process death:

  • The app was in the background, Android killed the process to free memory.
  • The user returns — the system starts a new process.
  • The Activity is recreated: onCreate(Bundle) → onStart → onResume.
  • onRestart is NOT called — for the system, this is a new Activity instance.

How to protect against this: always save critical state in onSaveInstanceState(Bundle) (called before onStop) or use SavedStateHandle in ViewModel. In onCreate, check savedInstanceState: if it is not null, restore state from Bundle; if null, load fresh data.

According to Google Android Vitals, about 7% of returns to an Activity after a long time in the background occur after process death. This means that every 15th Activity that should have called onRestart actually goes through onCreate. Ignoring this scenario is one of the main causes of “empty screen after return” bugs.

Code examples with onRestart in Kotlin

Example 1: onRestart with list update via ViewModel

The Activity calls viewModel.refreshTasks() in onRestart to update the task list after returning from the edit screen.

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", "Received ${tasks.size} tasks")
        }
    }

    override fun onRestart() {
        super.onRestart()
        Log.d("TaskList", "onRestart: updating task list")
        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() loads current data from the repository. LiveData automatically notifies the Activity of data changes — the UI updates without additional code. onRestart does not create a new subscription — it was already set up in onCreate.

Example 2: onRestart with authorization check

The Activity checks token validity upon return and redirects to login if necessary.

kotlin
class ProfileActivity : AppCompatActivity() {
    private val authManager = AuthManager()
    private val launcher = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { Log.d("Profile", "Returned from login screen") }

    override fun onRestart() {
        super.onRestart()
        if (!authManager.isTokenValid()) {
            Log.d("Profile", "Token expired — redirecting to login")
            launcher.launch(Intent(this, LoginActivity::class.java))
        }
    }
}

class AuthManager {
    fun isTokenValid(): Boolean {
        val expiry = SharedPreferencesManager().getTokenExpiry()
        return System.currentTimeMillis() < expiry
    }
}

If the user minimized the app for a long time and returned after the token expired, onRestart will redirect them to the login screen. This prevents API errors when attempting to make a request with an expired token. Note: the check is in onRestart, not in onResume, to avoid an unnecessary check when returning from a dialog.

Example 3: onRestart in Fragment with ViewLifecycleOwner

The Fragment uses onRestart via LifecycleObserver to update data.

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 via LifecycleObserver")
                viewModel.refreshFeed()
            }
        })
    }
}

Instead of overriding onRestart in Fragment, LifecycleObserver is used — a more flexible approach that allows adding lifecycle event logic without inheritance. ViewLifecycleOwner ensures that the observer lives within the View scope (it does not outlive onDestroyView).

Frequently Asked Questions

How is onRestart different from onResume?

onResume is called every time the Activity gains focus — including when returning from a dialog or system menu (the Activity did not go into onStop). onRestart is only called when returning from the Stopped state, when the Activity was completely hidden. onRestart is a narrower event for “heavy” updates, while onResume is for lightweight operations (changing the title, updating the time).

Can onRestart be called without onStop?

No, it cannot. onRestart is a paired method with onStop: onRestart is only called after the Activity has gone through onStop. If the Activity did not go into onStop (e.g., a dialog box was opened), then upon return onRestart is not called — only onResume.

How to simulate onRestart in the emulator?

Press Home (the house button) in the emulator — the Activity will minimize and receive onStop. Then open the app through Recent Apps or the launcher — the Activity will receive onRestart → onStart → onResume. For debugging, use Debug with breakpoints in onRestart or Log.d with the Activity tag.

What happens if an exception is thrown in onRestart?

An uncaught exception in onRestart will cause a Force Close. The system does not catch exceptions in lifecycle callbacks. If onRestart performs operations that could throw an exception (network request without try-catch, working with a null View), wrap them in try-catch.

Do I need to check isFinishing() in onRestart?

No. onRestart is only called for live Activities that are returning from the Stopped state. isFinishing() in onRestart will always be false. Checking isFinishing() makes sense in onPause (saving data) and onDestroy (distinguishing recreation from finish()).

Summary

  • onRestart — a lifecycle method called when an Activity returns from the Stopped state, before onStart and onResume.
  • onRestart is NOT called when the Activity is first created — only when it is shown again after being completely hidden.
  • The main purpose of onRestart is updating stale data and checking status (token, network, settings).
  • onRestart is not called during process death — use onCreate with Bundle for restoration after process death.
  • Do not duplicate onCreate logic in onRestart: do initialization in onCreate, updates in onRestart.
  • For Fragment, use LifecycleObserver on viewLifecycleOwner instead of overriding onRestart.
  • Proper implementation of onRestart improves UX during multitasking and prevents displaying stale data.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also