В чем разница между remember и rememberSaveable в Jetpack Compose
Что проверяют
Понимаете ли вы, что одно переживает рекомпозицию, а другое ещё и пересоздание активности.
Как отвечать
remember сохраняет значение между рекомпозициями. Пока композиция жива, значение не пересчитывается. Но при пересоздании активности (поворот экрана, смена темы, смена языка) композиция создаётся заново, и значение теряется.
rememberSaveable дополнительно сохраняет значение в Bundle через тот же механизм, что и onSaveInstanceState. Поэтому оно переживает и пересоздание активности, и убийство процесса системой при уходе приложения в фон.
var query by rememberSaveable { mutableStateOf("") } // текст переживёт поворот
val listState = rememberLazyListState() // позиция прокрутки, тоже saveableОграничение rememberSaveable: значение должно помещаться в Bundle. Примитивы, строки и Parcelable работают сразу, для своих типов нужен Saver (listSaver, mapSaver) или аннотация @Parcelize. И размер ограничен: класть туда список из тысячи элементов нельзя, транзакция Binder этого не переживёт.
Как выбирать: то, что человек ввёл или выбрал (текст поиска, выбранная вкладка, позиция прокрутки, состояние диалога), в rememberSaveable. То, что дёшево пересоздать (вычисленный формат, объект-помощник, анимационное состояние), в remember.
И отдельно: данные экрана, приходящие из сети, не место ни там, ни там. Их держит ViewModel, которая переживает поворот сама, а вместе с SavedStateHandle и смерть процесса.
Где спотыкаются
Держат в remember введённый пользователем текст и теряют его при повороте.
Кладут в rememberSaveable крупные объекты.
Не пишут Saver для своего типа и получают ошибку во время выполнения.
Дублируют в rememberSaveable то, что уже хранится в ViewModel.