Назад к вопросам
Middle
105
questionbank

Как сохранить состояние ViewModel в архитектурных компонентах Android?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Сохранить состояние ViewModel можно несколькими способами:

  1. Использование SavedStateHandle: Предпочтительный способ для сохранения небольших объемов данных, необходимых для восстановления состояния после уничтожения процесса. SavedStateHandle предоставляет Map-подобный интерфейс для сохранения и получения данных.

    class MyViewModel(private val state: SavedStateHandle) : ViewModel() {
    
        private val _name = state.getLiveData<String>("name")
        val name: LiveData<String> = _name
    
        fun saveName(newName: String) {
            state.set("name", newName)
        }
    }
    
  2. Сохранение состояния в бандл (Bundle): Используется в связке с onSaveInstanceState для сохранения данных самого Activity или Fragment, а не напрямую ViewModel. Затем эти данные могут быть использованы для инициализации ViewModel при ее создании.

    // В Activity или Fragment
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        // Сохранение данных, которые потом будут использованы для инициализации ViewModel
        outState.putString("some_data_for_vm", "важное значение")
    }
    
    // Использование данных в ViewModel (через фабрику)
    class MyViewModelFactory(private val initialData: String) : ViewModelProvider.Factory {
        override fun <T : ViewModel?> create(modelClass: Class<T>): T {
            if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
                @Suppress("UNCHECKED_CAST")
                return MyViewModel(initialData) as T
            }
            throw IllegalArgumentException("Unknown ViewModel class")
        }
    }
    
    class MyViewModel(private val initialData: String) : ViewModel() {
        // Использование initialData для восстановления состояния
    }
    
  3. Сохранение данных в постоянном хранилище: Для сохранения более сложных или больших объемов данных можно использовать SharedPreferences, базы данных (например, Room) или файлы. ViewModel может взаимодействовать с репозиторием, который управляет доступом к этим данным.

    class MyViewModel(private val userRepository: UserRepository) : ViewModel() {
        fun saveUser(user: User) {
            userRepository.saveUser(user)
        }
    
        fun getUser(id: Long): LiveData<User> {
            return userRepository.getUser(id)
        }
    }
    
    // Пример UserRepository
    class UserRepository(private val userDao: UserDao) {
        fun saveUser(user: User) {
            // Логика сохранения в базу данных
        }
    
        fun getUser(id: Long): LiveData<User> {
            // Логика получения из базы данных
        }
    }
    

Выбор метода зависит от типа и объема сохраняемых данных, а также от того, какие сценарии восстановления состояния необходимо поддерживать (например, уничтожение процесса vs смена конфигурации). SavedStateHandle является наиболее подходящим для сохранения состояния, которое необходимо пережить уничтожение процесса и восстановить UI.