How ViewModel Survives Configuration Changes

yadunath narayanan
3 min readDec 23, 2020

--

I hope you know the basic concept of view model before reading this article. As you know one of the most important property of viewmodel is it will survive android’s configuration changes. So when the user rotates the screen developer does not need to store the data, it is already available in viewmodel. But viewmodel won’t store the data when the activity/fragment is destroyed. That means viewmodel persists only in screen rotation changes. But when you are rotating screen also activity is destroyed and recreated, then how viewmodel is handling only in this scenario? One interviewer asked me this question , which I was not able to answer.So I went through the viewmodel code,and understood the flow.

When user rotates screen, your activity/fragment’s onCreate will get called, we will be initializing viewmodel with viewmodelprovider in onCreate only. Then there is a chance for viewmodelprovider is a handling it, but if you check viewmodelprovider internal implementation

@NonNull
@MainThread
public static ViewModelProvider of(@NonNull FragmentActivity activity,@Nullable Factory factory) {
Application application = checkApplication(activity);
if (factory == null) {
factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
}
return new ViewModelProvider(activity.getViewModelStore(), factory);
}

every time it’s creating a new ViewModelProvider , but if you see first argument ,its activity.getViewModelStore() , which means there is a store for viewmodel in android.

/**
* Class to store {
@code ViewModels}.
* <p>
* An instance of {
@code ViewModelStore} must be retained through configuration changes:
* if an owner of this {
@code ViewModelStore} is destroyed and recreated due to configuration
* changes, new instance of an owner should still have the same old instance of
* {
@code ViewModelStore}.
* <p>
* If an owner of this {
@code ViewModelStore} is destroyed and is not going to be recreated,
* then it should call {
@link #clear()} on this {@code ViewModelStore}, so {@code ViewModels} would
* be notified that they are no longer used.
* <p>
* Use {
@link ViewModelStoreOwner#getViewModelStore()} to retrieve a {@code ViewModelStore} for
* activities and fragments.
*/
public class ViewModelStore {
private final HashMap<String, ViewModel> mMap = new HashMap<>();final void put(String key, ViewModel viewModel) {
ViewModel oldViewModel = mMap.put(key, viewModel);
if (oldViewModel != null) {
oldViewModel.onCleared();
}
}
final ViewModel get(String key) {
return mMap.get(key);
}
Set<String> keys() {
return new HashSet<>(mMap.keySet());
}
/**
* Clears internal storage and notifies ViewModels that they are no longer used.
*/
public final void clear() {
for (ViewModel vm : mMap.values()) {
vm.clear();
}
mMap.clear();
}
}

ViewModelStore is an object which contains a HashMap of String and ViewModel.key is the default key and value is viewmodel.

This viewmodelstore is maintained by activity, we can confirm that by checking the implementation of activity.getViewmodelStore()

if (mViewModelStore == null) {
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
// Restore the ViewModelStore from NonConfigurationInstances
mViewModelStore = nc.viewModelStore;
}
if (mViewModelStore == null) {
mViewModelStore = new ViewModelStore();
}
}

So here if configuration changes happened, if already a viewmodelstore is available then it will return that instance else a new viewmodelstore is created.

This is how viewmodel persists on screen rotation. And when finish is called it activity will call viewmodel.clear().

I hope you understood how viewmodel is surviving configuration changes.

--

--

yadunath narayanan
yadunath narayanan

Written by yadunath narayanan

Passionate android developer working with android mobile and androidTv

No responses yet