В чём разница между remember и rememberSaveable? Когда использовать каждый?

Что делает remember

@Composable
fun Counter() {
    var count by remember { mutableStateOf(0) }
    ...
}

remember хранит значение внутри композиции (в slot table), живёт, пока компонент находится в Composition и переживает рекомпозиции. Но значение теряется, когда: Composable вышел из дерева (ветка if выключилась, сменился экран и т.п.) или Activity/Process был уничтожен (например, поворот экрана).

remember как бы говорит компилятору «помни, пока этот кусок UI живёт».

Что делает rememberSaveable

@Composable
fun Counter() {
    var count by rememberSaveable { mutableStateOf(0) }
    ...
}

rememberSaveable работает как remember, но поверх этого сохраняет значение в SavedStateRegistry / Bundle. rememberSaveable умеет восстанавливаться после поворота экрана (configuration change) и после recreate Activity (например, по нехватке памяти, когда система убила процесс и восстановила назад с savedInstanceState). Но по умолчанию сохраняет только то, что умеет ложиться в Bundle:
Int, Long, String, Boolean, List этих типов, Parcelable, Serializable и т.д.

rememberSaveable говорит компилятору «помни, даже если экран пересоздали”».

Как это выглядит в жизненном цикле

remember:

  • Initial composition => вычислил блок, положил в слот
  • Recomposition => значение берёт из слота, блок не вызывается
  • Composable вышел из Composition => слот удалён => стейт потерян
  • Activity пересоздали (rotate) => всё начинается с нуля

rememberSaveable:

  • Initial composition => как remember, плюс регистрирует Saver
  • При сохранении стейта (onSaveInstanceState) => значение кладётся в Bundle
  • При recreate => из Bundle значение восстанавливается и кладётся обратно в слот

Опубликовано

в

от

Метки: