Повторное построение не равно новому экрану
Compose повторно выполняет функции интерфейса, когда нужно отразить изменившееся состояние. Это называют рекомпозицией. Механизм remember позволяет удерживать значение в составе текущей композиции между такими повторными выполнениями. Он не превращает значение в долговременно сохранённую запись. Если соответствующая часть интерфейса удалена из композиции, связанное с ней запомненное значение может быть утрачено. Пересоздание Activity при изменении конфигурации также не является обычной рекомпозицией. Поэтому успешное обновление надписи на экране ещё не проверяет восстановление после пересоздания. Представим учебный каталог открыток. Пользователь ввёл название города, а рядом изменился счётчик найденных карточек. Если строка сохранилась, это подтверждает поведение только в данном сценарии. Из него нельзя заключить, что ввод переживёт все способы закрытия и восстановления приложения.
Для восстановления нужен подходящий механизм
Небольшое состояние интерфейса, поддерживаемое механизмом сохранения, можно удерживать через rememberSaveable. Он использует сохранённое состояние экземпляра и помогает восстанавливать данные при пересоздании Activity и предусмотренном системой восстановлении после завершения процесса. Это не универсальная гарантия сохранности после любого действия пользователя. Например, принудительное закрытие или удаление задачи нельзя безоговорочно приравнивать к системному завершению фонового процесса. Сначала нужно определить конкретный сценарий, который должно поддерживать приложение. ViewModel решает другую часть задачи: удерживает состояние соответствующего экрана и связанную логику через изменения конфигурации. Сам объект ViewModel не переживает завершение процесса. Для небольших восстанавливаемых значений в таком случае может применяться SavedStateHandle, а для долговременных данных нужен соответствующий слой хранения. Выбор зависит от назначения данных и архитектуры, а не от желания заменить всё одним названием.
Сохраняйте смысл, а не весь экран целиком
Вернёмся к каталогу. В нём есть короткая строка поиска, выбранная карточка и коллекция открыток, отмеченных пользователем как любимые. Строка и идентификатор карточки помогают восстановить текущее положение человека в интерфейсе. Коллекция избранного имеет более долгую жизнь: пользователь ожидает увидеть её и при следующем обычном запуске. Если хранить избранное только как временное состояние экрана, это ожидание может нарушиться. Напротив, большой список объектов не стоит помещать в механизм сохранённого состояния экземпляра: его объём ограничен. Полезнее сохранить минимальный идентификатор или ключ, а содержательные данные восстановить из подходящего постоянного хранилища. Такой разбор начинается с вопроса, сколько должна жить информация. Потом определяют владельца состояния, способ сохранения и отдельный сценарий проверки. Проверка рекомпозиции, пересоздания Activity и восстановления после системного завершения процесса отвечает на разные вопросы. Один успешный поворот экрана не заменяет все эти проверки. Бумажная схема ниже помогает сформулировать требования, но не доказывает работоспособность конкретной реализации. В настоящем приложении поведение нужно проверять подходящими тестами и средствами платформы.
Попробуйте на практике
Разложите состояние вымышленного каталога по назначению. Код, устройство и личные данные не нужны.
- Нарисуйте три карточки: короткая строка поиска, идентификатор открытой открытки, постоянно сохраняемое избранное.
- Для каждой подпишите, должна ли она восстанавливаться при пересоздании текущего экрана и при следующем обычном запуске по требованиям примера.
- Отдельно нарисуйте события: рекомпозиция, пересоздание Activity, системное завершение процесса. Не объединяйте их в одно событие.
- Укажите, почему remember недостаточно для всех требований и почему избранное нельзя полагать сохранённым только за счёт временного состояния интерфейса.
Как проверить результат. Ответ различает временное восстановление и долговременные записи. ViewModel не назван переживающим завершение процесса сам по себе, а remember не представлен постоянным хранилищем.
Частые вопросы
rememberSaveable заменяет базу данных?
Нет. Он предназначен для подходящего небольшого состояния, восстанавливаемого механизмом платформы. Долговременные содержательные данные приложения требуют отдельного решения для хранения.
Если текст исчез, причина обязательно в remember?
Нет. Возможны ошибки владельца состояния, ключей, восстановления или логики приложения. Сначала нужно воспроизвести точное событие и проверить путь данных, а затем выбирать исправление.
Самостоятельный разбор темы. Содержание конкретной обучающей программы здесь не представлено.