← Назад к вопросам

Что такое функция rememberSavable?

2.0 Middle🔥 203 комментариев
#UI и вёрстка

Комментарии (3)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Функция rememberSavable в Jetpack Compose

rememberSavable — это расширенная версия функции remember в Jetpack Compose, которая позволяет сохранять состояние композиции не только во время рекомпозиции, но и при изменении конфигурации (например, повороте экрана) и даже между перезапусками процесса, используя механизм SavedInstanceState.

Основное предназначение

В отличие от обычного remember, который хранит состояние только в течение жизни композиции (до ее выхода из Composition), rememberSavable автоматически сохраняет данные в Bundle при уничтожении активити/фрагмента и восстанавливает их при повторном создании. Это критически важно для:

  • Сохранения UI-состояния при повороте устройства
  • Восстановления данных после убийства процесса системой (process death)
  • Работы с конфигурационными изменениями без потери введенных пользователем данных

Ключевые характеристики

@Composable
fun <T : Any> rememberSavable(
    vararg inputs: Any?,
    saver: Saver<T, out Any> = autoSaver(),
    key: String? = null,
    init: () -> T
): T

Параметры:

  • inputs — зависимости, при изменении которых значение будет пересчитываться (аналогично remember)
  • saver — определяет способ сериализации/десериализации значения
  • key — дополнительный ключ для идентификации в Bundle
  • init — инициализатор, создающий начальное значение

Работа с Saver-ами

Saver — это интерфейс, определяющий как объект преобразуется в сохраняемое состояние и обратно:

interface Saver<T : Any, Saveable : Any> {
    fun SaverScope.save(value: T): Saveable?
    fun restore(value: Saveable): T?
}

Jetpack Compose предоставляет несколько встроенных Saver-ов:

  1. autoSaver() — автоматически работает с типами, поддерживающими @Parcelize
  2. listSaver(), mapSaver() — для коллекций
  3. Создание кастомных Saver-ов для сложных объектов

Примеры использования

Базовый пример с примитивными типами:

@Composable
fun CounterScreen() {
    // Состояние сохранится при повороте экрана
    var count by rememberSavable { mutableStateOf(0) }
    
    Column {
        Text("Count: $count")
        Button(onClick = { count++ }) {
            Text("Increment")
        }
    }
}

Работа с кастомными объектами:

@Parcelize
data class UserSettings(
    val theme: String,
    val notificationsEnabled: Boolean
) : Parcelable

@Composable
fun SettingsScreen() {
    // autoSaver автоматически использует Parcelable
    var settings by rememberSavable { mutableStateOf(UserSettings("Light", true)) }
    
    // ... UI для изменения настроек
}

Кастомный Saver для сложных объектов:

data class ComplexData(val id: Int, val name: String)

val complexDataSaver = run {
    mapSaver<ComplexData>(
        save = { mapOf("id" to it.id, "name" to it.name) },
        restore = { ComplexData(it["id"] as Int, it["name"] as String) }
    )
}

@Composable
fun ComplexScreen() {
    var data by rememberSavable(
        saver = complexDataSaver
    ) { mutableStateOf(ComplexData(1, "Test")) }
}

Внутренняя механика работы

  1. Сохранение: При уничтожении активити, Compose runtime собирает все значения, созданные через rememberSavable, и сохраняет их в Bundle через соответствующие Saver-ы
  2. Восстановление: При создании новой инстанции активити, Compose восстанавливает значения из Bundle и передает их в композицию
  3. Интеграция с remember: rememberSavable внутренне использует обычный remember, добавляя к нему логику сохранения/восстановления

Важные ограничения и лучшие практики

Ограничения:

  • Размер данных: Bundle имеет ограничения по размеру (обычно 500KB-1MB)
  • Производительность: Частое сохранение больших объектов может влиять на производительность
  • Типы данных: Не все типы можно сохранить по умолчанию

Рекомендации:

  • Используйте remember для временных UI-состояний (анимации, флаги)
  • Используйте rememberSavable для данных, которые должны пережить изменение конфигурации
  • Для больших или сложных данных используйте ViewModel + сохранение в базу данных/Preferences
  • Для объектов, не поддерживающих Parcelable, создавайте кастомные Saver-ы

Отличия от альтернативных подходов

ПодходСохраняет при поворотеСохраняет при убийстве процессаСложность
rememberНизкая
rememberSavableСредняя
ViewModel❌ (только с SavedStateHandle)Высокая
LocalSaveStateRegistryОчень высокая

Типичные сценарии использования

  1. Формы ввода данных — сохранять частично заполненные поля
  2. Состояние UI-компонентов — открытые/закрытые состояния раскрывающихся списков
  3. Текущий прогресс — в многошаговых процессах или wizard-ах
  4. Временные фильтры и сортировки — в списках данных

Функция rememberSavable заполняет важную нишу между простым remember и полноценными архитектурными компонентами, предоставляя удобный способ сохранения состояния без излишней сложности. Однако для управления бизнес-логикой и большими объемами данных рекомендуется использовать ViewModel в сочетании с SavedStateHandle, который internally также использует похожие механизмы сохранения состояния.

Что такое функция rememberSavable? | PrepBro