Как работает стек активностей с launch mode singleTop при нажатии кнопки назад
Что проверяют
Понимаете ли вы, что launch mode влияет на запуск активности, а не на кнопку «Назад». Следом обычно спрашивают, чем singleTop отличается от singleTask и в каком порядке идут колбэки жизненного цикла при onNewIntent().
Как отвечать
Правило singleTop одно: если экземпляр этой активности уже стоит на вершине целевой задачи, новый не создаётся, и система вызывает у него onNewIntent(). Если активность есть в стеке, но не наверху, создаётся новый экземпляр, как при standard. Тот же эффект даёт флаг FLAG_ACTIVITY_SINGLE_TOP.
Разберите на стеке:
- A, B, затем снова B: с
standardполучится A, B, B, и до A придётся нажать «Назад» дважды. СsingleTopстек остаётся A, B, у B вызываетсяonNewIntent(), и одно нажатие ведёт к A; - A, B, C, затем B: B не на вершине, поэтому стек станет A, B, C, B.
singleTopздесь ничего не меняет; - нажатие «Назад»: система завершает верхнюю активность (
onPause,onStop,onDestroy) и показывает предыдущую. Особой логики дляsingleTopнет.
Порядок колбэков при повторном запуске: onPause(), onNewIntent(), onResume(). Важная деталь: getIntent() по-прежнему вернёт старый интент, поэтому в onNewIntent() вызывают setIntent(intent) или сразу обрабатывают новые данные.
Упомяните современный контекст. С Android 12 «Назад» на корневой активности лаунчера не уничтожает её, а уводит задачу в фон. onBackPressed() устарел, возврат перехватывают через OnBackPressedDispatcher и OnBackPressedCallback, без этого не заработает жест predictive back.
Где спотыкаются
Говорят, что singleTop гарантирует один экземпляр в стеке. Это поведение singleTask, а singleTop проверяет только вершину.
Обрабатывают данные только в onCreate() и забывают про onNewIntent(). Повторный запуск с новыми extras тогда молча показывает старый экран.
Читают getIntent() в onNewIntent() или позже в onResume() и получают исходный интент, потому что не вызвали setIntent().