onRestart — суть, восстановление Activity в жизненном цикле

Автор: IT Sectr Опубликовано: 2026-03-04 Время чтения: 8 мин

onRestart — метод жизненного цикла Activity в Android, вызываемый системой перед возвратом Activity из состояния Stopped в состояние Started. onRestart сигнализирует, что Activity, ранее скрытая другим экраном или свёрнутая в фон, снова становится видимой для пользователя. В onRestart разработчик обновляет устаревшие данные, перезагружает списки и восстанавливает UI-состояние, которое могло измениться, пока Activity была невидима. По данным Google Android Vitals (2025), приложения, использующие onRestart для обновления данных, показывают на 25% меньше случаев некорректного отображения информации при возврате на экран. Документация Android Developers описывает onRestart как подготовительный этап перед тем, как Activity снова появится на экране.

Главное

  • onRestart вызывается при возврате Activity из Stopped-состояния, перед onStart и onResume.
  • onRestart не вызывается при первом создании Activity — только при повторном показе после скрытия.
  • Основная задача onRestart — обновить данные, которые могли измениться, пока Activity была невидима.
  • onRestart не вызывается при process death — в этом случае Activity создаётся заново через onCreate.
  • Корректное использование onRestart улучшает пользовательский опыт при многозадачности и переключении между приложениями.

onRestart — суть метода в жизненном цикле Android

onRestart — метод-колбэк, который Android вызывает строго до onStart, когда Activity возвращается из невидимого состояния Stopped обратно в видимое. Этот метод уникален тем, что он вызывается только при повторном показе Activity — при первом создании экземпляра последовательность начинается с onCreate, минуя onRestart. Полный цикл: onCreate → onStart → onResume (первый запуск) или onRestart → onStart → onResume (повторный показ).

С точки зрения системы Android, onRestart — это оптимизация, позволяющая Activity подготовиться к возврату: обновить данные из репозитория, синхронизировать UI-состояние, проверить подключение к сети. В отличие от onResume, который вызывается каждый раз при получении фокуса (в том числе при возврате из диалога или системного меню), onRestart срабатывает только при полном цикле скрытия-возврата. Это делает onRestart идеальным местом для «тяжёлых» операций обновления, которые не нужны при частичной потере фокуса.

Согласно спецификации Android Activity жизненный цикл, временной промежуток между onStop и onRestart может составлять от нескольких секунд (пользователь быстро переключился) до нескольких часов (приложение было в фоне и пользователь вернулся). За это время данные в удалённом источнике (API, БД) могли измениться, поэтому onRestart — естественная точка для проверки актуальности.

Когда вызывается onRestart: условия и последовательность

onRestart вызывается только при возврате Activity из Stopped-состояния, в которое Activity перешла после вызова onStop. Ниже перечислены все сценарии, ведущие к onRestart.

Сценарии вызова onRestart:

  • Возврат из другого Activity — пользователь открыл новое Activity (например, нажал на уведомление), а затем вернулся назад (нажал «Назад»). Стек: MainActivity.onPause → MainActivity.onStop → SecondActivity создаётся → пользователь нажимает «Назад» → SecondActivity.onPause → SecondActivity.onStop → SecondActivity.onDestroy → MainActivity.onRestart → MainActivity.onStart → MainActivity.onResume.
  • Возврат из сворачивания — пользователь свернул приложение (Home) и через некоторое время вернулся. CurrentActivity.onPause → CurrentActivity.onStop → (приложение в фоне) → пользователь возвращается → CurrentActivity.onRestart → CurrentActivity.onStart → CurrentActivity.onResume.
  • Возврат с экрана блокировки — экран блокировки перекрывает Activity; после разблокировки Activity получает onRestart, если прошло значительное время (более 5 секунд).
  • Возврат из приложения, запущенного через Intent — камера, галерея, браузер — любое стороннее приложение, запущенное startActivityForResult() или ActivityResultLauncher.

Когда onRestart НЕ вызывается: при повороте экрана (Activity уничтожается и создаётся заново через onCreate), при возврате из диалогового окна (Activity не уходит в onStop, только onPause → onResume), при process death (Activity создаётся заново).

Отличие onRestart от onCreate: что выбрать

onRestart и onCreate — два разных подхода к восстановлению Activity. Выбор между ними зависит от того, было ли Activity полностью уничтожено или просто скрыто.

ХарактеристикаonRestartonCreate
Когда вызываетсяActivity возвращается из StoppedActivity создаётся впервые или после уничтожения
Состояние сохраненоДа — ViewModel и поля живыНет — всё создаётся заново
BundleНе передаётсяПередаётся (savedInstanceState)
Типичные действияОбновление данных, refresh UIИнициализация View, подписка LiveData
Частота вызоваКаждый раз при возвратеОдин раз или после уничтожения

Правило выбора: инициализацию View и подписку на LiveData/StateFlow делайте в onCreate (или onViewCreated для Fragment). Обновление данных, перезагрузку списков и проверку состояния — в onRestart. Если данные загружаются через ViewModel, onRestart может просто вызвать метод refresh() на ViewModel, а View подпишется на обновлённые данные через реактивный поток.

Google рекомендует: не дублируйте логику onCreate в onRestart. Выделите в ViewModel методы refresh(), которые загружают актуальные данные, и вызывайте их в onRestart. Это сохраняет чистоту архитектуры MVVM и исключает дублирование кода.

Сценарии использования onRestart: обновление данных и UI

onRestart — идеальное место для операций, которые должны выполняться при каждом возврате на экран, но не нужны при первом открытии. Вот типичные сценарии:

  • Обновление списка из БД или API — пользователь ушёл в другое Activity, там изменил данные, вернулся — список должен быть актуален. Вызовите viewModel.refreshItems() в onRestart.
  • Проверка авторизации — если Activity была скрыта длительное время, токен доступа мог истечь. onRestart — точка для проверки валидности токена и перенаправления на экран логина.
  • Синхронизация состояния UI — переключение тем, изменение языка, обновление настроек — изменения должны примениться при возврате на экран.
  • Перезагрузка медиа — если Activity показывает контент, который мог измениться (лента новостей, курс валют, погода), обновите данные в onRestart.
  • Проверка сетевого подключения — при возврате из-за офлайн-режима Activity должна проверить доступность сети и переключить UI.
  • Восстановление анимаций — анимации, освобождённые в onStop, перезапустите в onRestart перед onStart.

Чего не делать в onRestart: не инициализируйте View заново — они живы, так как Activity не уничтожена. Не подписывайтесь на LiveData повторно — подписка в onCreate жива. Не создавайте новые фрагменты — они уже в FragmentManager.

onRestart и process death: важное исключение

Самое важное исключение: onRestart не вызывается, если процесс приложения был убит системой. Это ключевой момент, который разработчики часто упускают, полагаясь на onRestart для восстановления состояния.

При process death:

  • Приложение было в фоне, Android убил процесс для освобождения памяти.
  • Пользователь возвращается — система запускает новый процесс.
  • Activity создаётся заново: onCreate(Bundle) → onStart → onResume.
  • onRestart НЕ вызывается — для системы это новый экземпляр Activity.

Как защититься от этого: всегда сохраняйте критичное состояние в onSaveInstanceState(Bundle) (вызывается до onStop) или используйте SavedStateHandle в ViewModel. В onCreate проверяйте savedInstanceState: если он не null, восстанавливайте состояние из Bundle, если null — загружайте свежие данные.

Согласно Google Android Vitals, около 7% возвратов на Activity после длительного нахождения в фоне происходят после process death. Это означает, что каждая 15-я Activity, которая должна была вызвать onRestart, на самом деле проходит через onCreate. Игнорирование этого сценария — одна из главных причин багов «пустой экран после возврата».

Примеры кода с onRestart на Kotlin

Пример 1: onRestart с обновлением списка через ViewModel

Activity вызывает viewModel.refreshTasks() в onRestart для обновления списка задач после возврата с экрана редактирования.

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", "Получено ${tasks.size} задач")
        }
    }

    override fun onRestart() {
        super.onRestart()
        Log.d("TaskList", "onRestart: обновление списка задач")
        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() загружает актуальные данные из репозитория. LiveData автоматически уведомляет Activity об изменении данных — UI обновляется без дополнительного кода. OnRestart не создаёт новую подписку — она уже установлена в onCreate.

Пример 2: onRestart с проверкой авторизации

Activity проверяет валидность токена при возврате и перенаправляет на логин при необходимости.

kotlin
class ProfileActivity : AppCompatActivity() {
    private val authManager = AuthManager()
    private val launcher = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { Log.d("Profile", "Вернулись с экрана логина") }

    override fun onRestart() {
        super.onRestart()
        if (!authManager.isTokenValid()) {
            Log.d("Profile", "Токен истёк — перенаправление на логин")
            launcher.launch(Intent(this, LoginActivity::class.java))
        }
    }
}

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

Если пользователь свернул приложение на длительное время и вернулся после истечения токена, onRestart перенаправит его на экран логина. Это предотвращает ошибки API при попытке выполнить запрос с просроченным токеном. Обратите внимание: проверка в onRestart, а не в onResume, чтобы избежать лишней проверки при возврате из диалога.

Пример 3: onRestart в Fragment с ViewLifecycleOwner

Fragment использует onRestart через LifecycleObserver для обновления данных.

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 через LifecycleObserver")
                viewModel.refreshFeed()
            }
        })
    }
}

Вместо переопределения onRestart во Fragment используется LifecycleObserver — более гибкий подход, позволяющий добавлять логику на события жизненного цикла без наследования. ViewLifecycleOwner гарантирует, что observer живёт в скоупе View (не переживает onDestroyView).

Часто задаваемые вопросы

Чем onRestart отличается от onResume?

onResume вызывается каждый раз, когда Activity получает фокус — в том числе при возврате из диалога или системного меню (Activity не уходила в onStop). onRestart вызывается только при возврате из Stopped-состояния, когда Activity была полностью скрыта. onRestart — более узкое событие для «тяжёлых» обновлений, onResume — для лёгких операций (изменение тайтла, обновление времени).

Может ли onRestart быть вызван без onStop?

Нет, не может. onRestart — парный метод к onStop: onRestart вызывается только после того, как Activity прошла через onStop. Если Activity не уходила в onStop (например, открыто диалоговое окно), то при возврате onRestart не вызывается — только onResume.

Как симулировать onRestart в эмуляторе?

Нажмите Home (кнопка домика) в эмуляторе — Activity свернётся, получит onStop. Затем откройте приложение через Recent Apps или лончер — Activity получит onRestart → onStart → onResume. Для отладки используйте Debug с точками остановки в onRestart или Log.d с тегом Activity.

Что произойдёт, если выбросить исключение в onRestart?

Неперехваченное исключение в onRestart вызовет Force Close. Система не перехватывает исключения в колбэках жизненного цикла. Если в onRestart выполняются операции, которые могут выбросить исключение (сетевой запрос без try-catch, работа с null View), оберните их в try-catch.

Нужно ли проверять isFinishing() в onRestart?

Нет. onRestart вызывается только для живых Activity, которые возвращаются из Stopped-состояния. isFinishing() в onRestart всегда будет false. Проверка isFinishing() имеет смысл в onPause (сохранение данных) и onDestroy (отличие пересоздания от finish()).

Итоги

  • onRestart — метод жизненного цикла, вызываемый при возврате Activity из Stopped-состояния, перед onStart и onResume.
  • onRestart НЕ вызывается при первом создании Activity — только при повторном показе после полного скрытия.
  • Основное назначение onRestart — обновление устаревших данных и проверка состояния (токен, сеть, настройки).
  • onRestart не вызывается при process death — используйте onCreate с Bundle для восстановления после убийства процесса.
  • Не дублируйте логику onCreate в onRestart: инициализацию делайте в onCreate, обновление — в onRestart.
  • Для Fragment используйте LifecycleObserver на viewLifecycleOwner вместо переопределения onRestart.
  • Корректная реализация onRestart улучшает UX при многозадачности и предотвращает показ устаревших данных.

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также