I was left with some questions regarding ViewModels after reading this:
https://developer.android.com/topic/libraries/architecture/saving-states
It says here that you should use a combination of both a ViewModel
for configuration changes (like screen rotation), and using onSaveInstanceState()
for all other cases where an activity is destroyed and then recreated in order to save the UI state.
My question is how do we know the way to restore the state when onCreate(Bundle)
is called - should I use the ViewModel or should I use the bundle received as a parameter? When the configuration changes, onSaveInstanceState()
is also called, and obviously onCreate()
is always called.
If I only restore the state from a ViewModel, it won't always remain with the correct data (since the activity could have been destroyed due to other reasons than configuration changes). If I only use the bundle I save in onSaveInstanceState()
then why would I use a ViewModel
to begin with?
In order to save sates of UI, I override onSaveInstanceState(Bundle savedInstanceState) and save all the data of the UI in savedInstanceState Bundle. This method is called before onStop() in older versions of Android (till android 8.0) and can be called after onStop() for newer versions. super.
UI state is usually stored or referenced in ViewModel objects and not activities, so using onSaveInstanceState() requires some boilerplate that the saved state module can handle for you. When using this module, ViewModel objects receive a SavedStateHandle object through its constructor.
Use a combination of ViewModels, the onSaveInstanceState() method, and/or persistent local storage to preserve an activity's UI state across configuration changes.
The onSaveInstanceState() method allows you to add key/value pairs to the outState of the app. Then the onRestoreInstanceState() method will allow you to retrieve the value and set it back to the variable from which it was originally collected.
onSaveInstanceState () can store a minimum number of data and not large amount of it. Saved State of ViewModel can be considered as a replacement for onSaveInstanceState () as it can also store the data because UI data is always referenced from ViewModel of Architecture Components and not the View (Activity/Fragment).
As mentioned in Saving UI States , ViewModel objects can handle configuration changes, so you don't need to worry about state in rotations or other cases. However, if you need to handle system-initiated process death, you might want to use onSaveInstanceState () as backup.
You pass the query from the onSaveInstanceState () bundle to the ViewModel, which will determine that it already has loaded the necessary data and that it does not need to re-query the database. This is one sane way to handle saving and restoring activity state.
Saved State module for ViewModel Part of Android Jetpack. As mentioned in Saving UI States , ViewModel objects can handle configuration changes, so you don't need to worry about state in rotations or other cases. However, if you need to handle system-initiated process death, you might want to use onSaveInstanceState () as backup.
I think it's good to think of this sources as a chain. You have 2 sources of data - ViewModel, that is faster but lives less and saved instance state that is slower but lives longer.
The rule is simple - try using your ViewModel and if it is not populated use the bundle from onSaveInstanceState().
When you do val model = ViewModelProviders.of(this).get(MyViewModel::class.java)
in onCreate() you can check if you get a new instance of viewModel. Then, if it is a new instance (i.e. it's data fields are empty) you can get some basic data from your bundle, like content id, and fetch data from the backend or database based on that id, populate your new ViewModel with it and then populate your activity from the ViewModel (if you are using LiveData it will be very natural).
Next time onCreate is called you repeat the process, either populating your activity from ViewModel or populating your ViewModel using data in the Bundle and then populating your activity from your ViewModel.
Update: Actually there is very similar approach described in the official docs. The only difference is that you pass the bundle to ViewModel and it decides if it needs fetching data, I was not specific about this mechanism.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With