В чем разница между сохранением ViewModel и SaveInstanceState?
Комментарии (3)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между ViewModel и SavedInstanceState
ViewModel и SavedInstanceState — это два разных механизма сохранения данных в Android, предназначенные для разных сценариев и имеющие различные жизненные циклы.
Ключевые различия
| Аспект | ViewModel | SavedInstanceState |
|---|---|---|
| Назначение | Сохранение данных, связанных с 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 сохранять данные не только при конфигурационных изменениях, но и при временном уничтожении процесса системой, обеспечивая более надежное сохранение состояния приложения.