Architecture components ViewModel vs. savedInstanceState bundle
If someone is still looking to understand difference between onSavedState vs ViewModel here is the detailed explanation:
onSavedInstanceState : Primary usage of onSavedInstance was not to handle orientation change but to provide a mechanism to retrieve data if app/activity is destroyed by Android System. Example case when app is in background and Android system decide to kill this as it needs memory for some other high priority process then in this case before activity is destroyed onSavedInstanceState will be called.
onSavedInstanceState only stores the Parcelable data, that provides hint to restore the state for the user when activity restarts. It saves data in System server that is a separate process.
onSavedInstanceState has data limit. Only small amount of Parcelable data can be saved.
While for ViewModel
ViewModel object is part of Applications process memory and hence it is able to survive configuration changes. Once a process dies, ViewModel goes away and all the saved state will be lost. Hence when activity restarts, ViewModel has nothing in it.
It works as a cache for heavy objects.
There are no restrictions in ViewModel.
Important: Always remember ViewModel and SavedState work together. They are not replacement or alternative to each other.
A good explanation (and a solution to your problem) can be found in this blogpost. TLDR: the viewmodel is hosted inside a persisted fragment, which gets recreated together with the hosting activity.
From: Kristin Marsicano's Book “Android Programming: The Big Nerd Ranch Guide, 4th Edition.” :
ViewModel vs Saved Instance State
While saved instance state stores an activity record across process death, it also stores an activity record across a configuration change. When you first launch the activity, the saved instance state bundle is null. When you rotate the device, the OS calls onSaveInstanceState(Bundle) on your activity. The OS then passes the data you stashed in the bundle to onCreate(Bundle?).
ViewModel really shines when you use it to orchestrate dynamic data for the activity
ViewModel makes continuing a download operation across a configuration change simple. It also offers an easy way to keep data that was expensive to load in memory across a configuration change. And, as you have seen, ViewModel gets cleaned up automatically once the user finishes the activity.
ViewModel does not shine in the process death scenario since it gets wiped away from memory along with the process and everything in it. This is where saved instance state takes center stage. But saved instance state has its own limitations. Since saved instance state is serialized to disk, you should avoid stashing any large or complex objects.
lifecycle-viewmodel-savedstate is a new library that was just released to allow ViewModels to save their state across process death. This should alleviate some of the difficulties of using ViewModels alongside saved instance state from your activities.
Use saved instance state to store the minimal amount of information necessary to re-create the UI state (for example, the current question index). Use ViewModel to cache the rich set of data needed to populate the UI in memory across configuration changes for quick and easy access.
When the activity is re-created after process death, use the saved instance state information to set up the ViewModel as if the ViewModel and activity were never destroyed.
As of this writing, there is no easy way to determine whether an activity is being re-created after process death versus a configuration change. Why does this matter? A ViewModel stays in memory during a configuration change. So if you use the saved instance state data to update the ViewModel after the configuration change, you are making your app do unnecessary work. If the work causes the user to wait or uses their resources (like battery) unnecessarily, this redundant work is problematic.
One way to fix this problem is to make your ViewModel a little smarter. When setting a ViewModel value might result in more work, first check whether the data is fresh before doing the work to pull in and update the rest of the data.