Может ли onStop не вызваться при переходе между Activity
Что проверяют
Знаете ли вы точный порядок колбэков при переходе между экранами и понимаете ли, что onStop() зависит от видимости, а не от факта перехода. Следом обычно спрашивают, где тогда сохранять данные и отпускать ресурсы.
Как отвечать
Сначала назовите нормальный порядок, когда A запускает B: A.onPause(), затем B.onCreate(), B.onStart(), B.onResume(), и только потом A.onStop(). Вызывается он, когда Activity перестаёт быть видимой. Отсюда случаи, когда его не будет:
- прозрачная или диалоговая B: тема с
android:windowIsTranslucentили диалоговая тема. A остаётся видна под ней и получает толькоonPause(); - многооконный режим: соседнее окно не перекрывает A, и она не останавливается. С Android 10 все видимые Activity вообще остаются в resumed;
- картинка в картинке: Activity в PiP видна, поэтому она на паузе, а не остановлена;
finish()вonCreate(): система сразу вызываетonDestroy(), минуяonStart(),onResume(),onPause()иonStop();- смерть процесса: падение или принудительная остановка, пока Activity на экране. Колбэков нет вовсе.
Ещё нюанс: A.onStop() может заметно запаздывать. Система останавливает старую Activity, когда главный поток новой освобождается, а если он постоянно занят, например бесконечной анимацией, остановка приходит только по таймауту.
Выводы для практики. onPause() должен быть быстрым: B не начнёт создаваться, пока он не завершится. Сохранение и освобождение тяжёлых ресурсов переносят в onStop(), а в многооконном режиме камеру и плеер держат до onStop(), а не отпускают на паузе. Подписки удобнее вешать через repeatOnLifecycle(Lifecycle.State.STARTED).
Где спотыкаются
Утверждают, что onStop() гарантированно идёт за onPause(). Прозрачная Activity поверх опровергает это за минуту.
Повторяют миф, что finish() с немедленным переходом пропускает onStop(). После onResume() вызов finish() проходит полный путь до onDestroy().
Сохраняют данные в onDestroy(). После onStop() процесс могут убить без дальнейших колбэков, а у приложений с targetSdk от 28 и onSaveInstanceState() вызывается уже после onStop().