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

В чем разница между сохранением ViewModel и SaveInstanceState?

2.0 Middle🔥 243 комментариев
#Android компоненты#Жизненный цикл и навигация

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

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

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

Разница между ViewModel и SavedInstanceState

ViewModel и SavedInstanceState — это два разных механизма сохранения данных в Android, предназначенные для разных сценариев и имеющие различные жизненные циклы.

Ключевые различия

АспектViewModelSavedInstanceState
НазначениеСохранение данных, связанных с UI, при конфигурационных изменениях (поворот экрана, изменение языка).Сохранение минимального состояния UI при уничтожении процесса системой (low memory) или при переходе между активити.
Объем данныхМожет хранить большие объемы данных (например, списки, объекты).Предназначен для небольших, примитивных данных (строки, числа), сериализуемых в Bundle.
Время жизниСуществует, пока жива соответствующая scope (активити, фрагмент, навигационный граф).Сохраняется только между onSaveInstanceState() и onCreate() или onRestoreInstanceState().
Способ храненияХранится в памяти, в компоненте ViewModelStore.Данные сериализуются в Bundle и передаются системой.
ИспользованиеДля данных, которые долго загружаются (сеть, БД) и не должны перезагружаться при повороте.Для восстановления состояния UI (текст в полях, позиция скролла) после уничтожения процесса.

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

SavedInstanceState

Используется для сохранения простых данных при уничтожении активити системой:

class MainActivity : AppCompatActivity() {
    private var userInput: String = ""

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putString("USER_INPUT_KEY", userInput)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        if (savedInstanceState != null) {
            userInput = savedInstanceState.getString("USER_INPUT_KEY", "")
            // Восстанавливаем UI
            editText.setText(userInput)
        }
    }
}

ViewModel

Для сохранения данных при конфигурационных изменениях:

class UserViewModel : ViewModel() {
    private val _userList = MutableLiveData<List<User>>()
    val userList: LiveData<List<User>> = _userList
    
    fun loadUsers() {
        // Загрузка данных из сети/БД
        viewModelScope.launch {
            val users = repository.loadUsers()
            _userList.value = users
        }
    }
}

class UserActivity : AppCompatActivity() {
    private lateinit var viewModel: UserViewModel
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // ViewModel переживет поворот экрана
        viewModel = ViewModelProvider(this).get(UserViewModel::class.java)
        
        viewModel.userList.observe(this) { users ->
            // Обновляем UI с полученными данными
            adapter.submitList(users)
        }
        
        // Загружаем данные только при первом создании
        if (savedInstanceState == null) {
            viewModel.loadUsers()
        }
    }
}

Когда что использовать

Используйте SavedInstanceState когда:

  • Нужно сохранить состояние UI элементов (текст в EditText, позиция в RecyclerView)
  • Восстановление необходимо после уничтожения процесса системой
  • Данные имеют небольшой объем и могут быть сериализованы

Используйте ViewModel когда:

  • Данные загружаются из сети или базы данных
  • Нужно сохранить состояние при повороте экрана
  • Работаете с LiveData, StateFlow, или другими реактивными потоками
  • Данные являются сложными объектами или коллекциями

Совместное использование

В реальных приложениях часто используют оба подхода вместе. ViewModel отвечает за хранение бизнес-данных, а SavedInstanceState — за состояние UI. Новый подход SavedStateHandle в ViewModel позволяет интегрировать оба механизма:

class MyViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() {
    companion object {
        private const val SEARCH_QUERY_KEY = "search_query"
    }
    
    var searchQuery: String
        get() = savedStateHandle[SEARCH_QUERY_KEY] ?: ""
        set(value) = savedStateHandle.set(SEARCH_QUERY_KEY, value)
    
    // LiveData, привязанный к SavedStateHandle
    val queryLiveData = savedStateHandle.getLiveData<String>(SEARCH_QUERY_KEY)
}

Такой подход позволяет ViewModel сохранять данные не только при конфигурационных изменениях, но и при временном уничтожении процесса системой, обеспечивая более надежное сохранение состояния приложения.