В какой метод жизненного цикла Android входит Bundle для сохранения состояния
Что проверяют
Знаете ли вы, когда система сохраняет состояние экрана и где его потом отдаёт, и понимаете ли разницу между поворотом экрана и смертью процесса. Следом обычно спрашивают, чем Bundle отличается от ViewModel и сколько данных в него можно положить.
Как отвечать
Сохранение идёт в onSaveInstanceState(outState: Bundle). Система вызывает его, когда активность уничтожается с возможностью вернуться: смена конфигурации, уход в фон с последующей выгрузкой процесса. Для приложений с targetSdk 28 и выше этот вызов идёт после onStop(), для более старых до него.
Восстановить можно в двух местах:
onCreate(savedInstanceState): при первом запускеBundleравенnull, поэтому проверка обязательна;onRestoreInstanceState(savedInstanceState): вызывается послеonStart()и только если состояние есть, проверять наnullне нужно.
Важные детали:
- когда не вызывается: если пользователь сам закрыл экран кнопкой «Назад» или код вызвал
finish(), состояние не сохраняется, экран уходит насовсем; - что сохраняется само: состояние
Viewс заданнымid, например текст вEditText; - объём:
Bundleпередаётся через Binder, у которого общий буфер транзакций около 1 МБ на процесс. С Android 7.0 превышение даётTransactionTooLargeException, поэтому храните идентификаторы и позиции, а не списки и картинки; - современная связка:
ViewModelпереживает поворот, но не смерть процесса. Для второго случая в неё передаютSavedStateHandle, а в Compose используютrememberSaveable.
Смерть процесса проверяют так: отправляют приложение в фон, выполняют adb shell am kill <package> и возвращаются в него из списка недавних.
Где спотыкаются
Называют только onCreate, не знают про onRestoreInstanceState или путают, в каком порядке он идёт относительно onStart().
Считают, что onSaveInstanceState вызывается при любом закрытии экрана, и сохраняют там черновик. Для постоянных данных нужна база или DataStore.
Кладут в Bundle большой список или Bitmap. На поворотах это может работать, а при уходе в фон приложение падает с TransactionTooLargeException.