How to save the state of a ViewModel in Android architecture components?
sobes.tech AI
Answer from AI
The state of ViewModel can be saved in several ways:
-
Using SavedStateHandle: The preferred method for saving small amounts of data needed to restore state after process destruction.
SavedStateHandleprovides a map-like interface for saving and retrieving data.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) } } -
Saving state in a bundle (Bundle): Used in conjunction with
onSaveInstanceStateto save data of theActivityorFragment, not directly ofViewModel. These data can then be used to initialize theViewModelwhen it is created.// In Activity or Fragment override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) // Saving data that will later be used to initialize ViewModel outState.putString("some_data_for_vm", "important value") } // Using data in ViewModel (via factory) 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() { // Using initialData to restore state } -
Saving data in persistent storage: For saving more complex or larger data volumes, you can use SharedPreferences, databases (e.g., Room), or files.
ViewModelcan interact with a repository that manages access to these data.class MyViewModel(private val userRepository: UserRepository) : ViewModel() { fun saveUser(user: User) { userRepository.saveUser(user) } fun getUser(id: Long): LiveData<User> { return userRepository.getUser(id) } } // Example UserRepository class UserRepository(private val userDao: UserDao) { fun saveUser(user: User) { // Logic to save in database } fun getUser(id: Long): LiveData<User> { // Logic to retrieve from database } }
The choice of method depends on the type and volume of data being saved, as well as the scenarios for restoring state (e.g., process destruction vs configuration change). SavedStateHandle is the most suitable for saving state that needs to survive process destruction and restore UI.