onRestart — метод жизненного цикла Activity в Android, вызываемый системой перед возвратом Activity из состояния Stopped в состояние Started. onRestart сигнализирует, что Activity, ранее скрытая другим экраном или свёрнутая в фон, снова становится видимой для пользователя. В onRestart разработчик обновляет устаревшие данные, перезагружает списки и восстанавливает UI-состояние, которое могло измениться, пока Activity была невидима. По данным Google Android Vitals (2025), приложения, использующие onRestart для обновления данных, показывают на 25% меньше случаев некорректного отображения информации при возврате на экран. Документация Android Developers описывает onRestart как подготовительный этап перед тем, как Activity снова появится на экране.
Главное
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 вызывается только при возврате Activity из Stopped-состояния, в которое Activity перешла после вызова onStop. Ниже перечислены все сценарии, ведущие к onRestart.
Сценарии вызова onRestart:
Когда onRestart НЕ вызывается: при повороте экрана (Activity уничтожается и создаётся заново через onCreate), при возврате из диалогового окна (Activity не уходит в onStop, только onPause → onResume), при process death (Activity создаётся заново).
onRestart и onCreate — два разных подхода к восстановлению Activity. Выбор между ними зависит от того, было ли Activity полностью уничтожено или просто скрыто.
| Характеристика | onRestart | onCreate |
|---|---|---|
| Когда вызывается | Activity возвращается из Stopped | Activity создаётся впервые или после уничтожения |
| Состояние сохранено | Да — 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 — идеальное место для операций, которые должны выполняться при каждом возврате на экран, но не нужны при первом открытии. Вот типичные сценарии:
viewModel.refreshItems() в onRestart.Чего не делать в onRestart: не инициализируйте View заново — они живы, так как Activity не уничтожена. Не подписывайтесь на LiveData повторно — подписка в onCreate жива. Не создавайте новые фрагменты — они уже в FragmentManager.
Самое важное исключение: onRestart не вызывается, если процесс приложения был убит системой. Это ключевой момент, который разработчики часто упускают, полагаясь на onRestart для восстановления состояния.
При process death:
Как защититься от этого: всегда сохраняйте критичное состояние в onSaveInstanceState(Bundle) (вызывается до onStop) или используйте SavedStateHandle в ViewModel. В onCreate проверяйте savedInstanceState: если он не null, восстанавливайте состояние из Bundle, если null — загружайте свежие данные.
Согласно Google Android Vitals, около 7% возвратов на Activity после длительного нахождения в фоне происходят после process death. Это означает, что каждая 15-я Activity, которая должна была вызвать onRestart, на самом деле проходит через onCreate. Игнорирование этого сценария — одна из главных причин багов «пустой экран после возврата».
Activity вызывает viewModel.refreshTasks() в onRestart для обновления списка задач после возврата с экрана редактирования.
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.
Activity проверяет валидность токена при возврате и перенаправляет на логин при необходимости.
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, чтобы избежать лишней проверки при возврате из диалога.
Fragment использует onRestart через LifecycleObserver для обновления данных.
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).
Часто задаваемые вопросы
onResume вызывается каждый раз, когда Activity получает фокус — в том числе при возврате из диалога или системного меню (Activity не уходила в onStop). onRestart вызывается только при возврате из Stopped-состояния, когда Activity была полностью скрыта. onRestart — более узкое событие для «тяжёлых» обновлений, onResume — для лёгких операций (изменение тайтла, обновление времени).
Нет, не может. onRestart — парный метод к onStop: onRestart вызывается только после того, как Activity прошла через onStop. Если Activity не уходила в onStop (например, открыто диалоговое окно), то при возврате onRestart не вызывается — только onResume.
Нажмите Home (кнопка домика) в эмуляторе — Activity свернётся, получит onStop. Затем откройте приложение через Recent Apps или лончер — Activity получит onRestart → onStart → onResume. Для отладки используйте Debug с точками остановки в onRestart или Log.d с тегом Activity.
Неперехваченное исключение в onRestart вызовет Force Close. Система не перехватывает исключения в колбэках жизненного цикла. Если в onRestart выполняются операции, которые могут выбросить исключение (сетевой запрос без try-catch, работа с null View), оберните их в try-catch.
Нет. onRestart вызывается только для живых Activity, которые возвращаются из Stopped-состояния. isFinishing() в onRestart всегда будет false. Проверка isFinishing() имеет смысл в onPause (сохранение данных) и onDestroy (отличие пересоздания от finish()).
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также