目录

  • Activity创立ViewModel
  • Activity重建ViewModel坚持存在的完成

    • relaunch之后新的Activity获取之前的viewModel
    • relaunch过程中保存旧Activity的viewModel
  • reference

2022/08/21

Activity创立ViewModel

  • 创立ViewModel

    // MyActivity#onCreate()
    val mainViewModel = 
                [V1]   ViewModelProvider(this)
                  [V2]       .get(MainViewModel::class.java)
    
  • [V1]

    ViewModelProvider结构函数

    // androidx.lifecycle.ViewModelProvider#get(java.lang.Class<T>)
        public constructor(
            owner: ViewModelStoreOwner
        ) : this(owner.viewModelStore, defaultFactory(owner), defaultCreationExtras(owner))
    

    this指MyActivity,即MyActivity应该是[I]ViewModelStoreOwner类型

    MyActivity承继[C]ComponentActivity],ComponentActivity完成了[I]ViewModelStoreOwner接口

    // CompnentActivity
    public class ComponentActivity extends androidx.core.app.ComponentActivity implements
            // ...
            ViewModelStoreOwner,
            // ... {
    

    this(owner.viewModelStore, defaultFactory(owner), defaultCreationExtras(owner)) ,这儿运用 owner.viewModelStore从ViewModelStoreOwner中取出[OC]ViewModelStore]

    // ViewModelStoreOwner
    interface ViewModelStoreOwner {
        /**
         * The owned [ViewModelStore]
         */
        val viewModelStore: ViewModelStore
    }
    

    然后调用下面的结构函数

    // ViewModelStoreOwner
    /**
     * Creates a ViewModelProvider
     *
     * @param store `ViewModelStore` where ViewModels will be stored.
     * @param factory factory a `Factory` which will be used to instantiate new `ViewModels`
     * @param defaultCreationExtras extras to pass to a factory
     */
    @JvmOverloads
    constructor(
        private val store: ViewModelStore,
        private val factory: Factory,
        private val defaultCreationExtras: CreationExtras = CreationExtras.Empty,
    ) {
    
  • [V2]

    调用了get办法⬇️

    // androidx.lifecycle.ViewModelProvider#get(java.lang.Class<T>)
        @MainThread
        public open operator fun <T : ViewModel> get(modelClass: Class<T>): T {
            val canonicalName = modelClass.canonicalName
                ?: throw IllegalArgumentException("Local and anonymous classes can not be ViewModels")
       [W1]  return get("$DEFAULT_KEY:$canonicalName", modelClass)
        }
    
  • [W1]

    // androidx.lifecycle.ViewModelProvider#get(java.lang.String, java.lang.Class<T>)
        @MainThread
        public open operator fun <T : ViewModel> get(key: String, modelClass: Class<T>): T {
        [X1]val viewModel = store[key]
        [X1]if (modelClass.isInstance(viewModel)) {
                ....
        [X1]    return viewModel as T
            ....
        [X2]return try {
        [X2]     factory.create(modelClass, extras)
        [X2] catch (e: AbstractMethodError) {
        [X2]    factory.create(modelClass)
        [X2]}.also { store.put(key, it) }
        }
    
  • [X1]⬅️[W1]

    从store([OC]ViewModelStore)中能找到viewmodel则直接回来

  • [X2]⬅️[W1]

    store中找不到则需要新创立一个viewmodel并放入store,这儿说明只需运用同一个ViewModelStore获取ViewModel则不同当地获取到的都是同一个ViewModel

    [OC]ViewModelStore看起来是个Map,事实上他的完成便是保护一个map,放出get和put办法

    open class ViewModelStore {
        private val map = mutableMapOf<String, ViewModel>()
        ...
        fun put(key: String, viewModel: ViewModel) {
        }
        operator fun get(key: String): ViewModel? {
            return map[key]
        }
        ...
    }
    

总结上面,Activity在onCreate时创立viewModel,Activity是一个ViewModelStoreOwner其间有一个ViewModelStore其间保护一个map,ViewModelProvier作为一个工具类在运用默许的/我们供给的Factory(为了适配结构函数有参的ViewModel)创立ViewModel的一起会将其存入这个map。

所以,在relaunch过程中,毁掉旧的Activity时假如能保存它的mViewModelStore,然后将其赋值新的Activity的mViewModelStore就能完成装备改变viewModel不改变的效果。

Activity重建ViewModel坚持存在的完成

relaunch之后新的Activity获取之前的viewModel

viewModel存在ViewModelStore中,说明ViewModelStore在Activity重建的过程中能坚持存在,看下[C]ComponentActivity怎么怎么获取[OC]ViewModelStore

    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.");
        }
   [T1] ensureViewModelStore();
        return mViewModelStore;
    }
  • [T1]

    在getViewModelStore()办法中调用了ensureViewModelStore()保证mViewModelStore不为空

        @SuppressWarnings("WeakerAccess") /* synthetic access */
        void ensureViewModelStore() {
            if (mViewModelStore == null) {
            [U1] NonConfigurationInstances nc =
                        (NonConfigurationInstances) getLastNonConfigurationInstance();
                if (nc != null) {
                    // Restore the ViewModelStore from NonConfigurationInstances
            [U2]    mViewModelStore = nc.viewModelStore;
                }
                if (mViewModelStore == null) {
                    mViewModelStore = new ViewModelStore();
                }
            }
        }
    
  • [U1]⬅️[T1]

    // Activity
        @Nullable
        public Object getLastNonConfigurationInstance() {
            return mLastNonConfigurationInstances != null
                    ? mLastNonConfigurationInstances.activity : null;
        }
    

    Activirty.mLastNonConfigurationInstances类型为[C]Activity.NonConfigurationInstances

    // android.app.Activity.NonConfigurationInstances
        static final class NonConfigurationInstances {
            Object activity;
            ....
        }
    

    mLastNonConfigurationInstances.activity在[U1]⬅️[T1]处被强转为[C]ComponentActivity.NonConfigurationInstances

    // androidx.activity.ComponentActivity.NonConfigurationInstances
        static final class NonConfigurationInstances {
            Object custom;
            ViewModelStore viewModelStore;
        }
    
  • [U2]⬅️[T1]

    假如[U1]获取的nc不为空,则将mViewModelStore赋值为nc.viewModelStore 即Activity.mLastNonConfigurationInstances.activity.viewModelStore

    所以想要保存给新Activity运用本来的viewModel,重点便是要在relaunch过程中保存旧的Activity.mLastNonConfigurationInstances然后再赋值给新Activity.mLastNonConfigurationInstances

relaunch过程中保存旧Activity的viewModel

设备改变,系统调用AMS的updateConfiguration 办法

ActivityManagerService.java – Android Code Search

// ActivityManagerService
    @Override
    public boolean updateConfiguration(Configuration values) {
        return mActivityTaskManager.updateConfiguration(values);
    }
// ActivityTaskManagerService
    @Override
    public boolean updateConfiguration(Configuration values) {
           ....
                updateConfigurationLocked(values, null, false, false /* persistent */,
           ....
    }
// ActivityTaskManagerService
    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
            boolean initLocale, boolean persistent, int userId, boolean deferResume,
            ActivityTaskManagerService.UpdateConfigurationResult result) {
            ....
            「I1」  changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId);
            ....
            「I2」 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
            ....
    }
  • 「I1」

    updateGlobalConfigurationLocked 更新当时装备信息

  • 「I2」

    ensureConfigAndVisibilityAfterUpdate 保证给定的activity更新运用的装备

    这儿starting传入的是null,需要ensureConfigAndVisibilityAfterUpdate中自己获取

    // ActivityTaskManagerService
        boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
            boolean kept = true;
         「J1」   final Task mainRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
            ....
                 「J2」 starting = mainRootTask.topRunningActivity();
            ....
                 「J3」 kept = starting.ensureActivityConfiguration(changes,
            ....
        }
    
  • 「J1」⬅️「I2」

    获取根窗口容器中当时具有焦点的尖端任务(root task)

  • 「J2」⬅️「I2」

    获取尖端任务(root task)中当时正在运转的尖端Activity(top running Activity)的ActivityRecord赋值给starting

  • 「J3」⬅️「I2」

    ActivityRecord对应的Activity更新Configuration

    // com.android.server.wm.ActivityRecord#ensureActivityConfiguration(int, boolean)
        boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) {
            return ensureActivityConfiguration(globalChanges, preserveWindow,
                    false /* ignoreVisibility */);
        }
    
    // com.android.server.wm.ActivityRecord#ensureActivityConfiguration(int, boolean, boolean)
        boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow,
                boolean ignoreVisibility) {
                ....
                    relaunchActivityLocked(preserveWindow);
                ....
        }
    
     // com.android.server.wm.ActivityRecord#relaunchActivityLocked
        void relaunchActivityLocked(boolean preserveWindow) {
                ....
           「K2」  final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
                ....
           「K1」  final ClientTransaction transaction = ClientTransaction.obtain(app.getThread(), token);
           「K2」  transaction.addCallback(callbackItem);
                ....
           「K3」  mAtmService.getLifecycleManager().scheduleTransaction(transaction);
                ....
        }
    
  • 「K1」⬅️「J3」

    token来自[C]ActivityRecord承继的[C]WindowToken中的token

    class WindowToken extends WindowContainer<WindowState> {
        private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowToken" : TAG_WM;
        /** The actual token */
        final IBinder token;
        /** The type of window this token is for, as per {@link WindowManager.LayoutParams} */
        final int windowType;
    
     // ClientTransaction
        /** Obtain an instance initialized with provided params. */
        public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
            ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
            if (instance == null) {
                instance = new ClientTransaction();
            }
            instance.mClient = client;
            instance.mActivityToken = activityToken;
            return instance;
        }
    

    将transaction.mActivityToken设置为ActivityRecord.token

  • 「K2」⬅️「J3」

    给transaction放入callback:[C]ActivityRelaunchItem

  • 「K3」⬅️「J3」

    履行transaction

    // com.android.server.wm.ClientLifecycleManager#scheduleTransaction(ClientTransaction)
        void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ....
            transaction.schedule();
            ....
        }
    
    // ClientTransaction
        public void schedule() throws RemoteException {
       「L1」  mClient.scheduleTransaction(this);
        }
    
  • 「L1」⬅️「K3」

    [C]ClientTransaction运用mClient履行自己

    • mClient是什么?
      // ClientTransaction
          /** Target client. */
          private IApplicationThread mClient;
      

      这儿是运用AIDL(根据Binder)进行进程间通信,对应文件IApplicationThread.aidl⬇️

      oneway interface IApplicationThread {
          ....
          void scheduleTransaction(in ClientTransaction transaction);
      

      这儿mClient是客户端,对应的客户端为[c]ApplicationThread

          private class ApplicationThread extends IApplicationThread.Stub {
      
  • 「M1」⬅️「L1」

    所以下面从 android.app.ActivityThread.ApplicationThread#scheduleTransaction办法继续

    // android.app.ActivityThread.ApplicationThread#scheduleTransaction
            @Override
            public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
                ActivityThread.this.scheduleTransaction(transaction);
            }
    

    这儿scheduleTransaction是调用的ActivityThread的基类ClientTransactonHandler中的scheduleTransaction办法

    // android.app.ClientTransactionHandler#scheduleTransaction
        void scheduleTransaction(ClientTransaction transaction) {
     「N1」  transaction.preExecute(this);
     「N2」  sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
        }
    
  • 「N1」⬅️「M1」

    为后面transaction的履行做些预备,这儿this传入的是[C]ActivityThread

        public void preExecute(android.app.ClientTransactionHandler clientTransactionHandler) {
            if (mActivityCallbacks != null) {
                ....
                for (int i = 0; i < size; ++i) {
                「O1」  mActivityCallbacks.get(i).preExecute(clientTransactionHandler, mActivityToken);
                ....
        }
    
  • 「O1」⬅️「N1」

    履行每个callback的preExecute办法,callback只有一个之前在「K2」处放入的ActivityRelaunchItem

     // android.app.servertransaction.ActivityRelaunchItem#preExecute
        public void preExecute(ClientTransactionHandler client, IBinder token) {
        「P1」 mActivityClientRecord = client.prepareRelaunchActivity(token, mPendingResults,
                    mPendingNewIntents, mConfigChanges, mConfig, mPreserveWindow);
        }
    
  • 「P1」⬅️ 「O1」

    从ActivityThread(即client)获取要relaunch的ActivityRecord存入ActivityRelaunchItem.mActivityClientRecord

        @Override
        public ActivityClientRecord prepareRelaunchActivity(IBinder token,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                int configChanges, MergedConfiguration config, boolean preserveWindow) {
        「Q1」     ....
        「Q2」     target = new ActivityClientRecord();
        「Q2」     target.token = token;
                    ....
        「Q3」     mRelaunchingActivities.add(target);
                    ....
            return ....target....;
        }
    
  • 「Q1」⬅️「P1」

    检查是否方针activity是否现已正在relaunch了,假如是则回来

  • 「Q2」⬅️「P1」

    方针activity没有现已正在relaunch(这儿认为是没有,这个判别只是为了避免relaunch正在relaunch的activity),则结构一个[sC]ActivityClientRecord记录要relaunch的Activity的token等信息

  • 「Q3」⬅️「P1」运用ActivityThread.mRelaunchingActivities记录一切要预备重启的ActivityClientRecord

    +-----------------------------------------------------+
    |                                                     |
    |                 ActivityThread                      |
    |                                                     |
    |       +-----------------------------------+         |
    |       |    mRelaunchingActivities         |         |
    |       |                                   |         |
    |       |   +------------------------+      |         |
    |       |   | ActivityClientRecord   |      |         |
    |       |   +------------------------+      |         |
    |       |                                   |         |
    |       |   +------------------------+      |         |
    |       |   | ActivityClientRecord   |      |         |
    |       |   +------------------------+      |         |
    |       |                                   |         |
    |       |           ....                    |         |
    |       |                                   |         |
    |       |                                   |         |
    |       +-----------------------------------+         |
    |                                                     |
    +-----------------------------------------------------+
    
  • 「N2」⬅️「M1」

    这儿运用Handler去真实履行transaction,obj传入的便是transaction

    // android.app.ClientTransactionHandler#sendMessage
        abstract void sendMessage(int what, Object obj);
    
    // android.app.ActivityThread#sendMessage(int, java.lang.Object)
        void sendMessage(int what, Object obj) {
            sendMessage(what, obj, 0, 0, false);
        }
    

    ⬇️结构Message

    // android.app.ActivityThread#sendMessage(int, java.lang.Object, int, int, boolean)
        private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
            ....
            msg.what = what;
            msg.obj = obj;
            ....
            mH.sendMessage(msg);
        }
    

    ⬇️handler:ActivityThread.H 收到音讯并处理

    // android.app.ActivityThread.H#handleMessage
            public void handleMessage(Message msg) {
                ...
                 switch (msg.what) {
                    ...
                    case EXECUTE_TRANSACTION:
                  「R1」  final ClientTransaction transaction = (ClientTransaction) msg.obj;
                  「R2」  mTransactionExecutor.execute(transaction);
                        ....
    
  • 「R1」⬅️「N2」从message中取出transaction

  • 「R2」⬅️「N2」交给mTransactionExecutor履行

    mTransactionHandler 是谁?是[C]ActivityThread,从TransactionExecutor的结构函数⬇️中能够看出

    // ActivityThread
        private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
    
        /** Initialize an instance with transaction handler, that will execute all requested actions. */
        public TransactionExecutor(ClientTransactionHandler clientTransactionHandler) {
            mTransactionHandler = clientTransactionHandler;
        }
    

    TransactionExecutor.mTransactionHandler是对持有该TransactionExecutor的ActivityThread的引证

    +-------------------------------------------------------------------------------------+
    |                                    ActivityThread <-------+                         |
    |                                                           |                         |
    |                                                           |                         |
    |      +-----------------------------------------------------------------+            |
    |      |  mTransactionExecutor: TransactionExecutor         |            |            |
    |      |                                                    |            |            |
    |      |                                                    |            |            |
    |      |  +-------------------------------------------------+---------+  |            |
    |      |  |   mTransactionHandler: ClientTransactionHandler           |  |            |
    |      |  |                                                           |  |            |
    |      |  |                                                           |  |            |
    |      |  +-----------------------------------------------------------+  |            |
    |      |                                                                 |            |
    |      |                                                                 |            |
    |      +-----------------------------------------------------------------+            |
    |                                                                                     |
    +-------------------------------------------------------------------------------------+
    
    // android.app.servertransaction.TransactionExecutor#execute
        public void execute(ClientTransaction transaction) {
            ....
            executeCallbacks(transaction);
            ....
        }
    
    // android.app.servertransaction.TransactionExecutor#executeCallbacks
        public void executeCallbacks(ClientTransaction transaction) {
            final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
            ....
      「S1」 final IBinder token = transaction.getActivityToken();
            ....
            for (int i = 0; i < size; ++i) {
                final ClientTransactionItem item = callbacks.get(i);
                ....
        「S2」  item.execute(mTransactionHandler, token, mPendingActions);
                ....
        }
    
  • 「S1」⬅️「R2」

    从transaction中获取activityToken「K1」⬅️「J3」

  • 「S2」⬅️「R2」

    callback(为ActivityRelaunchItem)履行,execute办法来自ActivityRelaunchItem 完成的接口BaseClientRequest的execute办法

    至于mTransactionHandler是谁,在「R2」现已解释

    execute办法来自ActivityRelaunchItem完成的接口BaseClientRequest中的execute办法⬇️

    public interface BaseClientRequest extends ObjectPoolItem {
        ....
        void execute(ClientTransactionHandler client, IBinder token,
                PendingTransactionActions pendingActions);
        ....
    }
    

    ActivityRelaunchItem和BaseClientRequest的关系⬇️

    public abstract class ClientTransactionItem implements BaseClientRequest
    
    public abstract class ActivityTransactionItem extends ClientTransactionItem
    
    public class ActivityRelaunchItem extends ActivityTransactionItem
    
    classDiagram
          class ClientTransactionItem {
          }
          class ActivityTransactionItem {
          }
          class ActivityRelaunchItem {
          }
          class BaseClientRequest {
             <<interface>>
             + execute(ClientTransactionHandler client, IBinder token,PendingTransactionActions pendingActions)
          }
          ClientTransactionItem <|-- ActivityTransactionItem
          ActivityTransactionItem <|-- ActivityRelaunchItem
          BaseClientRequest <|-- ClientTransactionItem: implements
    

    该execute办法由[C]ActivityRelaunchItem的基类ActivityTransactionItem完成

    // ActivityTransactionItem
        public final void execute(ClientTransactionHandler client, IBinder token,
                PendingTransactionActions pendingActions) {
       「A1」  final ActivityClientRecord r = getActivityClientRecord(client, token);
       「A2」  execute(client, r, pendingActions);
        }
    
  • 「A1」根据token获取ActivityClientRecord

    // ActivityTransactionItem
        @NonNull ActivityClientRecord getActivityClientRecord(
                @NonNull ClientTransactionHandler client, IBinder token) {
            final ActivityClientRecord r = client.getActivityClient(token);
            ....
            return r;
        }
    

    client是 TransactionExecutor.mTransactionHandler,也便是持有TransactionExecutor的ActivityThread

    // ActivityThread 
        @Override
        public ActivityClientRecord getActivityClient(IBinder token) {
            return mActivities.get(token);
        }
    
  • 「A2」继续履行 ⬇️

    // ActivityRelaunchItem
        @Override
        public void execute(ClientTransactionHandler client, ActivityClientRecord r,
                PendingTransactionActions pendingActions) {
            ....
      「B1」  client.handleRelaunchActivity(mActivityClientRecord, pendingActions);
        }
    
  • 「B1」mActivityClientRecord从哪里来?之前「P1」⬅️ 「O1」

    // ActivityThread
        @Override
        public void handleRelaunchActivity(ActivityClientRecord tmp,
                PendingTransactionActions pendingActions) {
            ...
        「C1」 ActivityClientRecord r = mActivities.get(tmp.token);
            ...
        「C2」handleRelaunchActivityInner(r, configChanges, tmp.pendingResults, tmp.pendingIntents,
                    pendingActions, tmp.startsNotResumed, tmp.overrideConfig, "handleRelaunchActivity");
            ...
        }
    
  • 「C1」⬅️「B1」

    这儿从mActivities中根据token获取[sC]ActivityClientRecord

    +----------------------------------------------------------------+
    |   ActivityThread                                               |
    |                                                                |
    |                                                                |
    |    +------------------------------------------------------+    |
    |    |  mActivities                                         |    |
    |    |             +--------------------------------------+ |    |
    |    |             |      +---------------+               | |    |
    |    |             |      |    Activity   |               | |    |
    |    |             |      +---------------+               | |    |
    |    |             |                                      | |    |
    |    |             |   +-------------------------------+  | |    |
    |    |             |   | lastNonConfigurationInstances |  | |    |
    |    |             |   +-------------------------------+  | |    |
    |    |             |                                      | |    |
    |    |             +--------------------------------------+ |    |
    |    |             +--------------------------------------+ |    |
    |    |             |                                      | |    |
    |    |             |                                      | |    |
    |    |             +--------------------------------------+ |    |
    |    |             +--------------------------------------+ |    |
    |    |             |                                      | |    |
    |    |             |                                      | |    |
    |    |             +--------------------------------------+ |    |
    |    |                                                      |    |
    |    |                           ...                        |    |
    |    |                                                      |    |
    |    +------------------------------------------------------+    |
    +----------------------------------------------------------------+
    
  • 「C2」⬅️「B1」

    传递r给

    // ActivityThread
        private void handleRelaunchActivityInner(ActivityClientRecord r, int configChanges,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingIntents,
                PendingTransactionActions pendingActions, boolean startsNotResumed,
                Configuration overrideConfig, String reason) {
            ...
    「D1」        handleDestroyActivity(r, false, configChanges, true, reason);
            ...
    「D2」        handleLaunchActivity(r, pendingActions, customIntent);
        }
    
  • 「D1」⬅️「C2」

    ⬇️Destroy本来的Activity,其间getNonConfigInstance传入了true

    // ActivityThread
        @Override
        public void handleDestroyActivity(ActivityClientRecord r, boolean finishing, int configChanges,
                boolean getNonConfigInstance, String reason) {
            performDestroyActivity(r, finishing, configChanges, getNonConfigInstance, reason);
            ...
        }
    

    ⬇️将本来的activity的nonConfigurationInstances存入ActivityRecord.lastNonConfigurationInstances

    // ActivityThread
        /** Core implementation of activity destroy call. */
        void performDestroyActivity(ActivityClientRecord r, boolean finishing,
                int configChanges, boolean getNonConfigInstance, String reason) {
            ...
        「E1」 if (getNonConfigInstance) {
                ....
                「E2」  r.lastNonConfigurationInstances = r.activity.retainNonConfigurationInstances();
                ....
    
  • 「E1」这儿假如是getNonConfigInstance为true(前面传的是true),

  • 「E2」

    则️将[sC]ActivityClientRecord中放入Java 代码块的成果,其间就包括viewModelStore

     // Activity
        NonConfigurationInstances retainNonConfigurationInstances() {
    「F1」 Object activity = onRetainNonConfigurationInstance();
            ...
            NonConfigurationInstances nci = new NonConfigurationInstances();
            nci.activity = activity;
            ....
            return nci;
        }
    
  • 「F1」Activity默许完成中只回来了null,可是[C]ComponentActivity重写了这个办法⬇️

     // ComponentActivity
        public final Object onRetainNonConfigurationInstance() {
            // Maintain backward compatibility.
    「G1」  Object custom = onRetainCustomNonConfigurationInstance();
            ViewModelStore viewModelStore = mViewModelStore;
    「G2」  if (viewModelStore == null) {
                ....
            }
            ....
    「G3」   NonConfigurationInstances nci = new NonConfigurationInstances();
            nci.custom = custom;
            nci.viewModelStore = viewModelStore;
            return nci;
        }
    
  • 「G1」我们能够经过重写onRetainCustomNonConfigurationInstance()创立custom即自定义的在configuration改变后仍然想要保存的数据。

  • 「G2」这儿当viewModelStore为空的时分会检查[C]ComponentActivity.NonConfigurationInstances中是否有viewModelStore,这儿对应从来没有当地调用过getViewModelStore,也就不会初始化ComponentActivity.mVieModelStore,可是我们这儿状况是之前有创立viewmodel,this(owner.viewModelStore, defaultFactory(owner), defaultCreationExtras(owner)) ,这儿运用 owner.viewModelStore从ViewModelStoreOwner中取出[OC]ViewModelStore调用过,一切不会走到viewModelStore == null的分支

  • 「G3」这儿创立了[C]ComponentActivity.NonConfigurationInstances存入 custom和viewModelStore并回来。

  • 「D2」⬅️「C2」履行LaunchActivity

    // android.app.ActivityThread#handleLaunchActivity
        public Activity handleLaunchActivity(ActivityClientRecord r,
                PendingTransactionActions pendingActions, Intent customIntent) {
            ....
            final Activity a = performLaunchActivity(r, customIntent);
            ....
            return a;
        }
    
    // android.app.ActivityThread#performLaunchActivity
        private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
            ....
            Activity activity = null;
            try {
                java.lang.ClassLoader cl = appContext.getClassLoader();
          「H1」 activity = mInstrumentation.newActivity(
                        cl, component.getClassName(), r.intent);
                ....
            try {
                ....
                if (activity != null) {
                    ....
            「H2」   activity.attach(appContext, this, getInstrumentation(), r.token,
                            r.ident, app, r.intent, r.activityInfo, title, r.parent,
                            r.embeddedID, r.lastNonConfigurationInstances, config,
                            r.referrer, r.voiceInteractor, window, r.activityConfigCallback,
                            r.assistToken, r.shareableActivityToken);
            ....
            return activity;
        }
    
  • 「H1」

    实例化一个Activity

  • 「H2」

    运用本来的ActivityRecord给Activity设置参数,其间第12个参数便是在「E2」处保存的lastNonConfigurationInstances,其间就有viewModel

    这儿就回答了上面[U2]处的问题,串起来了

reference

code

  • Android 面试总结 – ViewModel 是怎么保存和康复? – ()
  • Android Framework之Activity启动流程(一) | 柚子 | pomeloJiang
  • Zygote的启动流程 – ()
  • Android屏幕旋转源码探索及使用实践 | 奔哲明的博客 (benzblog.site)
  • Configuration 改变时Activity的生命周期探求 – ()