Saving Activity's State With OnSaveInstanceState() And ViewModel

I was left with some questions regarding ViewModels after reading this:

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?



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( 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.