Как закрыть несколько активностей в стеке Android
Что проверяют
Знаете ли вы, как устроены задача и back stack, и умеете ли подобрать инструмент под сценарий: вернуться на главный экран, выйти из аккаунта, закрыть цепочку оформления заказа. Следом обычно спрашивают, чем CLEAR_TOP отличается от CLEAR_TASK и как то же самое делается в Navigation.
Как отвечать
Разберите по сценариям:
- вернуться к экрану, который уже есть в стеке:
FLAG_ACTIVITY_CLEAR_TOPзакрывает всё, что выше целевой активности. СFLAG_ACTIVITY_SINGLE_TOPцелевой экземпляр сохраняется и получает интент вonNewIntent(), без него пересоздаётся; - начать с чистого листа, например после логаута:
FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASKочищает задачу целиком, новая активность становится корневой, и «назад» с неё выходит из приложения; - закрыть текущую и всё под ней:
finishAffinity()завершает активности с той же affinity в текущей задаче.finishAndRemoveTask()ещё и убирает задачу из недавних; - закрыть цепочку экранов по одному: приём с
setResult()иfinish()по цепочке работает, но результаты в новом коде передают через Activity Result API.
Скажите и о современном подходе. В приложении с одной активностью и Navigation Component экраны живут в back stack навигации, и закрытие нескольких сразу делается через popUpTo с inclusive = true в опциях перехода или navController.popBackStack(destinationId, inclusive). В Navigation Compose то же самое: navigate(route) { popUpTo(...) { inclusive = true } }.
Где спотыкаются
Ставят CLEAR_TOP без SINGLE_TOP для активности со стандартным launchMode и удивляются, что главный экран пересоздался и потерял состояние.
Складывают ссылки на активности в статический список, чтобы потом пройтись по нему finish(). Это утечка памяти: список держит уже уничтоженные экземпляры, и сборщик мусора не может их освободить после поворота экрана или закрытия.
Не смотрят на launchMode в манифесте. singleTask и singleInstance меняют поведение стека для всех запусков активности, и флаги в интенте поверх них дают неожиданный результат. Прежде чем ставить флаги, проверьте манифест и реальный стек через adb shell dumpsys activity activities.