Architecture component — ViewModel behind the scenes
In this article, I will dive into the implementation details of ViewModel and explain how it works behind the scenes.
In my previous article, I talked about one of the very important feature ViewModel has to offer is to be able to survive from a configuration change, so how does it achieve this? the short answer is by taking advantage of setRetainInstance(true)
from Fragment
, ViewModel uses a fragment with setRetainInstance
set to true behind the scenes.
The source code
Let's first look at the source code to see how ViewModels are stored/associated with an Activity.
All ViewModels
of an AppCompatActivity
are stored in a hashMap
inside ViewModelStore
. AppCompatActivity
is a ViewModelStoreOwner
who is capable of providing a ViewModelStore
instance to access its ViewModels
.
When a configuration change happened on an Activity, its onRetainNonConfigurationInstance()
callback method will be called to allow you to return an object that can be later retrieved in the newly created Activity via getLastNonConfigurationInstance()
. If we look into the source code of ComponentActivity
(who is a super class of AppCompatActivity
). We can see it returns an instance of wrapper class that contains viewModelStore
. Through this mechanism, ViewModels of an Activity are retained.
ComponentActivity class
Great! we now know how an Activity keeps its ViewModels, but how does Fragment work? Let’s keep digging into the source code.
Fragment class
setRetainInstance(bool)
will allow fragment instance to be retained during Activity re-creation, from the source code above, we can see that the work is delegated to amFragmentManager
instance, below source code shows what happens when you call addRetainedFragment
and removeRetainedFragment
FragmentManager
class has a private property private FragmentManagerViewModel mNonConfig
who keeps track of all the fragments that need to be retained and a hash map that stores ViewModelStores and the fragments they belong in a key-value pair fashion with keys being a unique UUID of a fragment.
When a Fragment needs to retrieve its ViewModels from a ViewStore, it asks its FragmentManager
to do the work, FragmentManager
is responsible to keep track of retained fragments and their ViewModelStores
.