Как проверить в onDestroy, происходит ли смена конфигурации или активити уничтожается
Что проверяют
Знаете ли вы штатный API жизненного цикла или начнёте изобретать флаги. Вопрос почти всегда продолжается так: как ViewModel переживает поворот экрана и откуда она знает, что её пора очищать.
Как отвечать
Для этого у Activity есть два метода, и оба корректно работают внутри onDestroy():
isChangingConfigurations(): вернётtrue, если активити уничтожается, чтобы сразу пересоздаться с новой конфигурацией: поворот, смена языка, тёмная тема, изменение размера окна;isFinishing(): вернётtrue, если активити закрывается насовсем: вызванfinish()или пользователь ушёл назад.
override fun onDestroy() {
super.onDestroy()
if (isChangingConfigurations) {
// пересоздание, состояние нужно сохранить
} else if (isFinishing) {
// окончательное закрытие, освобождаем ресурсы
}
}Хорошо назвать и третий случай: оба метода вернули false. Так бывает, когда система уничтожает активити без закрытия, например с включённой опцией «Не сохранять действия» в настройках разработчика. А при убийстве процесса onDestroy() может не вызваться вовсе.
Ровно эту проверку делает ComponentActivity: при событии ON_DESTROY она очищает ViewModelStore, только если isChangingConfigurations() вернул false. Поэтому ViewModel переживает поворот и умирает при настоящем закрытии. Если в манифесте указан android:configChanges, активити при перечисленных изменениях не пересоздаётся, а получает onConfigurationChanged().
Где спотыкаются
Ставят свой флаг в onSaveInstanceState(). Этот метод вызывается и при обычном уходе в фон, так что флаг соврёт, а поле в любом случае пропадёт вместе со старым экземпляром активити.
Ждут onConfigurationChanged() при повороте. Без android:configChanges он не вызывается, активити просто пересоздаётся.
Держат в onDestroy() логику, без которой теряются данные. Этот колбэк не гарантирован, для сохранения есть onStop(), SavedStateHandle и rememberSaveable.