version

'androidx. Appcompat: appcompat: 1.2.0'Copy the code
If you want the ViewModel not to be destroyed with a host rebuild, make sure the ViewModelStore is not destroyed with a host rebuild. So when was the ViewModelStore saved?

A: by the onRetainNonConfigurationInstance ComponentActivity and getLastNonConfigurationInstance method save ViewModelStore object

First look at the getViewModelStore() method that gets ViewModelStore in ComponentActivity

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."); } the if (mViewModelStore = = null) {/ / get NonConfigurationInstances, If it is not empty to obtain viewModelStore NonConfigurationInstances nc = (NonConfigurationInstances) getLastNonConfigurationInstance (); if (nc ! = null) { // Restore the ViewModelStore from NonConfigurationInstances mViewModelStore = nc.viewModelStore; } if (mViewModelStore == null) {mViewModelStore = new ViewModelStore(); } } return mViewModelStore; }Copy the code
NonConfigurationInstances
static final class NonConfigurationInstances {
        Object custom;
        ViewModelStore viewModelStore;
    }
Copy the code

2. In the next see ComponentActivity onRetainNonConfigurationInstance () method of how to preserve viewModelStore

public final Object onRetainNonConfigurationInstance() { Object custom = onRetainCustomNonConfigurationInstance(); ViewModelStore viewModelStore = mViewModelStore; If (viewModelStore == null) {// If NonConfigurationInstance saves viewModelStore, Put it out NonConfigurationInstances nc = (NonConfigurationInstances) getLastNonConfigurationInstance (); if (nc ! = null) { viewModelStore = nc.viewModelStore; } } if (viewModelStore == null && custom == null) { return null; } NonConfigurationInstances nci = new NonConfigurationInstances(); nci.custom = custom; / / put viewModelStore NonConfigurationInstances and return, so that when the page is viewModelStore was saved when the reconstruction and destroyed the nci viewModelStore = viewModelStore;  return nci; }Copy the code
public Object getLastNonConfigurationInstance() { return mLastNonConfigurationInstances ! = null ? mLastNonConfigurationInstances.activity : null; }Copy the code

3. Then onRetainNonConfigurationInstance () method when the called?

During the Activity launch process, when the ActivityThread executes the performDestroyActivity method, Invokes the Activity of retainNonConfigurationInstances () method to obtain to save data and save the ActivityClientRecord.

/ / the Activity of retainNonConfigurationInstances () method NonConfigurationInstances retainNonConfigurationInstances () { / / ComponentActivity onRetainNonConfigurationInstance () method of the Object activity = onRetainNonConfigurationInstance (); ... NonConfigurationInstances nci = new NonConfigurationInstances (); nci.activity = activity; ... return nci; }Copy the code
ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing, int configChanges, boolean getNonConfigInstance, String reason) { ... / / save the data to the ActivityClientRecord ActivityClientRecord retainNonConfigurationInstances r = mActivities. Get (token); r.lastNonConfigurationInstances = r.activity.retainNonConfigurationInstances(); . return r;Copy the code

When the page is rebuilt and the ActivityThread executes the performLaunchActivity method, it calls the Attach method of the Activity and passes in the data it just stored.

Private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {// Transfer previously stored data activity.attach(......) , r.lastNonConfigurationInstances,.....) ; }Copy the code