SoFunction
Updated on 2025-03-11

In-depth explanation of the role of Android ViewModel

What is the function of ViewModel

The ViewModel class is designed to store and manage interface-related data in a life cycle-oriented manner. The ViewModel class allows data to be retained after configuration changes such as screen rotation (official explanation)

After seeing this, we can summarize the two functions of viewmodel. The first viewmodel will be cleared when the activity and fragment are destroyed. The second viewmodel can be rebuilt after the activity is destroyed.

Then the question is how viewmodel saves data and automatically releases memory? We will uncover these two questions when we understand the veil of viewmodel.

Then let's start with the simplest use of viewmodel

class UserViewModel : ViewModel() {
    var age: Int = 0
}
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        (savedInstanceState)
        val userViewModel =
            ViewModelProvider(this, ())[UserViewModel::]
        val mView = (layoutInflater)
        setContentView()
         = ()
        var sum = 0
         {
            sum = ()
             = sum
        }
    }
}

As we keep clicking the sum, the activity will become larger and larger. When we rotate the screen, the activity will be rebuilt. But the age we obtain is the value of the last click, which proves that our data is saved. So how does viewmodel do it? We analyze from the source code perspective

The following source code analysis was analyzed from Android 13

Looking at the source code viewmodel is an abstract class, you can't see anything. Then we have to think differently. Since the viewmodel has something to do with activity and can be reused when the activity is rotated and destroyed, then we will look for it from the activity.

One-level search and discover that a ViewModelStoreOwner interface is implemented in ComponentActivity. See if the naming is related to viewmodel, see what is inside this interface.

public interface ViewModelStoreOwner {
    /**
     * Returns owned {@link ViewModelStore}
     *
     * @return a {@code ViewModelStore}
     */
    @NonNull
    ViewModelStore getViewModelStore();
}
//The code is very concise. An abstract method. Return value. ViewModelStore. As the name suggests, the function of this class is about to be released. If you store the viewmodel, then we will see how to handle it in the implementation class.//Implemented in ComponentActivity  @NonNull
    @Override
    public ViewModelStore getViewModelStore() {
        if (getApplication() == null) {
            throw new IllegalStateException("Your activity is not yet attached to the "
                    + "Application instance. You can't request ViewModel before onCreate call.");
        }
        ensureViewModelStore();
        return mViewModelStore;
    }
// Let's look directly at the ensureViewModelStore() methodvoid ensureViewModelStore() {
        if (mViewModelStore == null) {
            NonConfigurationInstances nc =
                    (NonConfigurationInstances) getLastNonConfigurationInstance();
            if (nc != null) {
                // Restore the ViewModelStore from NonConfigurationInstances
                mViewModelStore = ;
            }
            if (mViewModelStore == null) {
                mViewModelStore = new ViewModelStore();
            }
        }
    }
 //The guaranteeViewModelStore method seems to be to obtain the ViewModelStore. So let’s take a look at what is done inside the ViewModelStore?public class ViewModelStore {
    private final HashMap<String, ViewModel> mMap = new HashMap<>();
    final void put(String key, ViewModel viewModel) {
        ViewModel oldViewModel = (key, viewModel);
        if (oldViewModel != null) {
            ();
        }
    }
    final ViewModel get(String key) {
        return (key);
    }
    Set<String> keys() {
        return new HashSet<>(());
    }
    /**
     *  Clears internal storage and notifies ViewModels that they are no longer used.
     */
    public final void clear() {
        for (ViewModel vm : ()) {
            ();
        }
        ();
    }
}
//It's clear to see this,As expected, it's the same as we thought,ViewModelStoreIt is used for cacheViewModelof

After our analysis, we have understood that the viewmodel is cached by the ViewModelStore. So how do we restore data when the activity is abnormally destroyed?

In ComponentActivity, there is another method to use ViewModelStore in discovery

onRetainNonConfigurationInstance method

public final Object onRetainNonConfigurationInstance() {
        // Maintain backward compatibility.
        Object custom = onRetainCustomNonConfigurationInstance();
        ViewModelStore viewModelStore = mViewModelStore;
        if (viewModelStore == null) {
            // No one called getViewModelStore(), so see if there was an existing
            // ViewModelStore from our last NonConfigurationInstance
            NonConfigurationInstances nc =
                    (NonConfigurationInstances) getLastNonConfigurationInstance();
            if (nc != null) {
                viewModelStore = ;
            }
        }
        if (viewModelStore == null && custom == null) {
            return null;
        }
        NonConfigurationInstances nci = new NonConfigurationInstances();
         = custom;
         = viewModelStore;
        return nci;
    }

The code inside the method body is also easy to understand. If the viewModelStore is null, then assign it a value. So when is this method implemented? After some debugging, it was found that when the activity switched to horizontal and vertical screens, this method was triggered, and the getViewModelStore method was executed when the activity was created. Now we know the time to create a viewModelStore, so how is viewModel stored in the viewModelStore?

Remember the sample code we wrote?

  val userViewModel =
            ViewModelProvider(this, ())
                .get(UserViewModel::)

Let's start with ViewModelProvider

 public constructor(owner: ViewModelStoreOwner, factory: Factory) : this(
        ,
        factory,
        defaultCreationExtras(owner)
    )

The first parameter is our activity instance and then we get our own viewModelStore. At this time, the viewModelStore has been created. Look at the second parameter is Factory. What we pass is NewInstanceFactory. This is a singleton. An internal create method is implemented.

  public open class NewInstanceFactory : Factory {
        @Suppress("DocumentExceptions")
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            return try {
                ()
            } catch (e: InstantiationException) {
                throw RuntimeException("Cannot create an instance of $modelClass", e)
            } catch (e: IllegalAccessException) {
                throw RuntimeException("Cannot create an instance of $modelClass", e)
            }
        }

A generic method returns a custom viewmodel instance, but still don't see how to store the viewmodel, don't worry

Let's look at the last call get method

 @MainThread
    public open operator fun <T : ViewModel> get(key: String, modelClass: Class<T>): T {
        val viewModel = store[key]
        if ((viewModel)) {
            (factory as? OnRequeryFactory)?.onRequery(viewModel)
            return viewModel as T
        } else {
            @Suppress("ControlFlowWithEmptyBody")
            if (viewModel != null) {
                // TODO: log a warning.
            }
        }
        val extras = MutableCreationExtras(defaultCreationExtras)
        extras[VIEW_MODEL_KEY] = key
        // AGP has some desugaring issues associated with compileOnly dependencies so we need to
        // fall back to the other create method to keep from crashing.
        return try {
            (modelClass, extras)
        } catch (e: AbstractMethodError) {
            (modelClass)
        }.also { (key, it) }
    }

The first choice is to get the viewmodel from the ViewModelStore. Looking inside the if statement, you can see that the cached viewmodel is returned directly. If it does not exist, the viewmodel will be instantiated based on the created factory and then stored in the ViewModelStore.

After our source code analysis, we now understand the stored procedures of viewmodel and the process of obtaining them when the activity is destroyed.

So how is the viewmodel destroyed? Remember the onCleared method in viewmodel? The comment states that when the ViewModel is no longer used and destroyed, this method will be called. Then let's see when this method was called

There is a clear method inside. This method is called by the clear method of ViewModelStore, and then it is inside the ComponentActivity

 getLifecycle().addObserver(new LifecycleEventObserver() {
            @Override
            public void onStateChanged(@NonNull LifecycleOwner source,
                    @NonNull  event) {
                if (event == .ON_DESTROY) {
                    // Clear out the available context
                    ();
                    // And clear the ViewModelStore
                    if (!isChangingConfigurations()) {
                        getViewModelStore().clear();
                    }
                }
            }
        });

When Lifecycle is used to monitor the life cycle, when the activity is not destroyed normally, the cached viewmodel is cleared. At this point, we understand how viewmodel implements data storage and data acquisition.

There is another point that needs additional explanation here. ViewModelStore is also obtained from the cache. The getLastNonConfigurationInstance method can be seen in the getViewModelStore method and the onRetainNonConfigurationInstance method. If you don’t want to null, just get the cached ViewModelStore, then you can naturally get the previously stored viewModel. As for how to cache, please study it yourself!

At this point, we have understood how viewmodel automatically clears and destroys the previous data of the reconstruction display when the activity is destroyed.

This is the end of this article about the role of Android ViewModel. For more related content on Android ViewModel, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!