В каком состоянии жизненный цикл активности при открытии прозрачной активности поверх другой
Что проверяют
Понимаете ли вы, что onStop зависит от видимости, а не от положения в стеке. Следом спрашивают, какие колбэки придут при закрытии прозрачной активности и что станет с камерой или видео в нижней.
Как отвечать
Пусть открыта A, поверх неё запускается прозрачная B. Порядок такой:
A.onPause(): A теряет фокус, но остаётся видимой сквозь B;B.onCreate(),B.onStart(),B.onResume(): B становится активной;A.onStop()не вызывается: система останавливает только полностью закрытые активности. В терминах Jetpack Lifecycle A остаётся в состоянииSTARTED.
При закрытии B: B.onPause(), затем A.onResume(), затем B.onStop() и B.onDestroy(). A возобновляется раньше, чем B останавливается, так передача фокуса устроена и в обычном случае.
Прозрачность задаётся темой окна: android:windowIsTranslucent в true плюс прозрачный windowBackground, либо готовая тема вроде Theme.Translucent.NoTitleBar или диалоговая. Если B непрозрачная, у A после паузы придёт onStop().
Практические следствия:
- подписки через
repeatOnLifecycle(Lifecycle.State.STARTED)в A продолжают работать, UI под B обновляется; - ресурсы: освобождать камеру или ставить видео на паузу в
onPauseили вonStop, решают осознанно. С Android 10 в многооконном режиме в состоянии resumed может быть несколько видимых активностей, поэтомуonPauseне означает «пользователь это не видит»; - ориентация: на Android 8.0 прозрачная активность с жёстко заданной
screenOrientationмогла падать сIllegalStateException, это важно при поддержке старых версий.
Где спотыкаются
Объясняют отсутствие onStop тем, что A «ещё в стеке». В стеке она остаётся и под непрозрачной B, но тогда onStop приходит. Причина только в видимости.
Путают порядок при возврате и думают, что B полностью уничтожается до A.onResume().
Делают прозрачным только фон в разметке, оставив непрозрачную тему окна. Тогда A честно получает onStop, а под B виден чёрный экран вместо предыдущей активности.