Как сохранять и восстанавливать состояние Activity в Android
Что проверяют
Различаете ли вы три разных сценария потери состояния и знаете ли ограничение по размеру.
Как отвечать
Сценариев три, и лечатся они по-разному:
- изменение конфигурации (поворот, смена темы или языка): активити пересоздаётся немедленно;
- убийство процесса в фоне: система выгружает приложение под нехваткой памяти, а при возврате воссоздаёт его с нуля;
- явное закрытие пользователем: состояние восстанавливать не нужно и не следует.
Средства:
onSaveInstanceState(Bundle) вызывается перед возможным уничтожением, восстановление идёт в onCreate из переданного набора или в onRestoreInstanceState. Переживает оба первых сценария. Главное ограничение: набор передаётся через Binder, и слишком большой объём даёт падение по превышению размера транзакции. Поэтому сюда кладут только небольшое состояние интерфейса: введённый текст, позицию прокрутки, выбранную вкладку.
ViewModel переживает изменение конфигурации, потому что живёт дольше активити. Но при убийстве процесса он теряется вместе с ним.
SavedStateHandle внутри ViewModel объединяет оба: данные сохраняются в тот же набор и переживают убийство процесса. Это современный основной способ.
rememberSaveable в Compose делает то же самое для состояния экрана.
Правило про большие данные: их не сохраняют, а перечитывают. В состоянии держат идентификатор, а сам объект берут из базы или репозитория. Список вакансий не место в наборе состояния.
Проверять это надо специально: в настройках разработчика включается режим, при котором активити уничтожается сразу после ухода в фон. Без него дефект не воспроизвести на своём устройстве, а у пользователей он проявится.
Где спотыкаются
Полагаются только на ViewModel и теряют состояние после убийства процесса.
Кладут в набор список объектов и ловят падение по размеру транзакции.
Не проверяют поведение при пересоздании процесса.
Восстанавливают состояние после явного закрытия приложения пользователем.