美文网首页
ViewModel 源码解析

ViewModel 源码解析

作者: 中路杀神ai | 来源:发表于2022-08-26 01:39 被阅读0次

    1.ViewModel 的创建

    ViewModelProvider(this)[ViewModelTest::class.java]

    默认构造
    public ViewModelProvider(@NonNull ViewModelStoreOwner owner) {
          
            this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory
                    ? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory()
                    : NewInstanceFactory.getInstance());
        }
    

    owner.getViewModelStore()
    ViewModelStoreOwner

    public class ComponentActivity extends androidx.core.app.ComponentActivity implements
            ContextAware,
            LifecycleOwner,
            ViewModelStoreOwner,
            HasDefaultViewModelProviderFactory,
            SavedStateRegistryOwner,
            OnBackPressedDispatcherOwner,
            ActivityResultRegistryOwner,
            ActivityResultCaller {
          
        @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;
        }
     }
      //
     void ensureViewModelStore() {
            if (mViewModelStore == null) {
                //先从最后一次保存的状态里获取
                NonConfigurationInstances nc =
                        (NonConfigurationInstances) getLastNonConfigurationInstance();
                if (nc != null) {
                    // Restore the ViewModelStore from NonConfigurationInstances
                    mViewModelStore = nc.viewModelStore;
                }
                //没有获取到直接创建新的
                if (mViewModelStore == null) {
                    mViewModelStore = new ViewModelStore();
                }
            }
        }
    
    
    @SuppressWarnings("WeakerAccess")
    public interface ViewModelStoreOwner {
        /**
         * Returns owned {@link ViewModelStore}
         *
         * @return a {@code ViewModelStore}
         */
        @NonNull
        ViewModelStore getViewModelStore();
    }
    

    ViewModelProvider(this)默认执行的Factory 为AndroidViewModelFactory

    @SuppressLint("LambdaLast")
        public SavedStateViewModelFactory(@Nullable Application application,
                @NonNull SavedStateRegistryOwner owner,
                @Nullable Bundle defaultArgs) {
            mSavedStateRegistry = owner.getSavedStateRegistry();
            mLifecycle = owner.getLifecycle();
            mDefaultArgs = defaultArgs;
            mApplication = application;
            mFactory = application != null
                    ? ViewModelProvider.AndroidViewModelFactory.getInstance(application)
                    : ViewModelProvider.NewInstanceFactory.getInstance();
        }
    

    ViewModelProvider(this)[ViewModelTest::class.java]的创建

    @NonNull
        @MainThread
        public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
          //首先从缓存中获取
            ViewModel viewModel = mViewModelStore.get(key);
    
            if (modelClass.isInstance(viewModel)) {
                if (mFactory instanceof OnRequeryFactory) {
                    ((OnRequeryFactory) mFactory).onRequery(viewModel);
                }
                return (T) viewModel;
            } else {
                //noinspection StatementWithEmptyBody
                if (viewModel != null) {
                    // TODO: log a warning.
                }
            }
            if (mFactory instanceof KeyedFactory) {
                viewModel = ((KeyedFactory) mFactory).create(key, modelClass);
            } else {
                //从工厂中创建
                viewModel = mFactory.create(modelClass);
            }
            //保存在ViewModelStore的HashMap里
            mViewModelStore.put(key, viewModel);
            return (T) viewModel;
        }
    
    

    AndroidViewModelFactory.create()
    反射创建ViewModel对象

            @NonNull
            @Override
            public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
                if (AndroidViewModel.class.isAssignableFrom(modelClass)) {
                    //noinspection TryWithIdenticalCatches
                    try {
                    //反射创建ViewModel对象
                        return modelClass.getConstructor(Application.class).newInstance(mApplication);
                    } catch (NoSuchMethodException e) {
                     
                }
                return super.create(modelClass);
            }
    

    ViewModelStore

    public class ViewModelStore {
      //key:   androidx.lifecycle.ViewModelProvider.DefaultKey:com.demo.arouter.ViewModelTest 
     //value:viewModel对象
        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();
        }
    }
    

    当手机配置发生改变(旋转屏幕)Activity 会销毁,重走onCreate
    在onDestory之前执行

    public final Object onRetainNonConfigurationInstance() {
            // Maintain backward compatibility.
            Object custom = onRetainCustomNonConfigurationInstance();
            
            ViewModelStore viewModelStore = mViewModelStore;
            if (viewModelStore == null) {
                //如果为空,从最后一个保存配置中读取
                NonConfigurationInstances nc =
                        (NonConfigurationInstances) getLastNonConfigurationInstance();
                if (nc != null) {
                    viewModelStore = nc.viewModelStore;
                }
            }
    
            if (viewModelStore == null && custom == null) {
                return null;
            }
            //创建 instances实例保存VewModelStore
            NonConfigurationInstances nci = new NonConfigurationInstances();
            nci.custom = custom;
            nci.viewModelStore = viewModelStore;
            return nci;
        }
    

    NonConfigurationInstances

    static final class NonConfigurationInstances {
            Object custom;
            ViewModelStore viewModelStore;
        }
    

    //状态恢复

     public ComponentActivity() {
            Lifecycle lifecycle = getLifecycle();
            //清除viewmodelStore里的viewmodel
            getLifecycle().addObserver(new LifecycleEventObserver() {
                @Override
                public void onStateChanged(@NonNull LifecycleOwner source,
                        @NonNull Lifecycle.Event event) {
                    if (event == Lifecycle.Event.ON_DESTROY) {
                        // Clear out the available context
                        mContextAwareHelper.clearAvailableContext();
                        // And clear the ViewModelStore
                        if (!isChangingConfigurations()) {
                            getViewModelStore().clear();
                        }
                    }
                }
            });
            //当执行onCreate 时候恢复数据
            getLifecycle().addObserver(new LifecycleEventObserver() {
                @Override
                public void onStateChanged(@NonNull LifecycleOwner source,
                        @NonNull Lifecycle.Event event) {
                    ensureViewModelStore();
                    getLifecycle().removeObserver(this);
                }
            });
    
           
        }
    

    2.onRetainNonConfigurationInstace,getLastNonConfigurationInstance()怎么保存和恢复的呢

    1.handleDestroyActivity

    @Override
        public void handleDestroyActivity(ActivityClientRecord r, boolean finishing, int configChanges,
                boolean getNonConfigInstance, String reason) {
            performDestroyActivity(r, finishing, configChanges, getNonConfigInstance, reason);
      
    void performDestroyActivity(ActivityClientRecord r, boolean finishing,
                int configChanges, boolean getNonConfigInstance, String reason) {
           ...
            //如果是配置发生改变
            if (getNonConfigInstance) {
               
                //把 retainNonConfigurationInstances的值复制给ActivityClientRecord的lastNonConfigurationInstances
              r.lastNonConfigurationInstances = r.activity.retainNonConfigurationInstances();
            }
          ...
          mInstrumentation.callActivityOnDestroy(r.activity);
    

    ActivityClientRecord 是保存在ActivityThread.java下的mActivities中

    // final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
    

    r.lastNonConfigurationInstances = r.activity.retainNonConfigurationInstances();

    NonConfigurationInstances retainNonConfigurationInstances() {
            //调用onRetainNonConfiguration()
            Object activity = onRetainNonConfigurationInstance();
            HashMap<String, Object> children = onRetainNonConfigurationChildInstances();
            FragmentManagerNonConfig fragments = mFragments.retainNestedNonConfig();
    
           
            mFragments.doLoaderStart();
            mFragments.doLoaderStop(true);
            ArrayMap<String, LoaderManager> loaders = mFragments.retainLoaderNonConfig();
    
            if (activity == null && children == null && fragments == null && loaders == null
                    && mVoiceInteractor == null) {
                return null;
            }
          //activity保存在 NonConfigurationInstances
            NonConfigurationInstances nci = new NonConfigurationInstances();
            nci.activity = activity;
            nci.children = children;
            nci.fragments = fragments;
            nci.loaders = loaders;
            if (mVoiceInteractor != null) {
                mVoiceInteractor.retainInstance();
                nci.voiceInteractor = mVoiceInteractor;
            }
            return nci;
        }
      
    

    NonConfigurationInstances

    static final class NonConfigurationInstances {
            Object activity;
            HashMap<String, Object> children;
            FragmentManagerNonConfig fragments;
            ArrayMap<String, LoaderManager> loaders;
            VoiceInteractor voiceInteractor;
        }
    

    执行完onDestory 对象已经保存在 r.lastNonConfigurationInstances

    handleLaunchActivity

     final Activity a = performLaunchActivity(r, customIntent);
    
     private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ....
        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.configCallback,
                            r.assistToken, r.shareableActivityToken);
      ....
    
    }
    

    将保存的对象赋值给Activity的 成员变量 mLastNonConfigurationInstances

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        final void attach(Context context, ActivityThread aThread,
                Instrumentation instr, IBinder token, int ident,
                Application application, Intent intent, ActivityInfo info,
                CharSequence title, Activity parent, String id,
                NonConfigurationInstances lastNonConfigurationInstances,
                Configuration config, String referrer, IVoiceInteractor voiceInteractor,
                Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken,
                IBinder shareableActivityToken) {
            attachBaseContext(context);
    
            mFragments.attachHost(null /*parent*/);
    
            mWindow = new PhoneWindow(this, window, activityConfigCallback);
            mWindow.setWindowControllerCallback(mWindowControllerCallback);
            mWindow.setCallback(this);
            mWindow.setOnWindowDismissedCallback(this);
            mWindow.getLayoutInflater().setPrivateFactory(this);
            if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
                mWindow.setSoftInputMode(info.softInputMode);
            }
            if (info.uiOptions != 0) {
                mWindow.setUiOptions(info.uiOptions);
            }
            mUiThread = Thread.currentThread();
    
            mMainThread = aThread;
            mInstrumentation = instr;
            mToken = token;
            mAssistToken = assistToken;
            mShareableActivityToken = shareableActivityToken;
            mIdent = ident;
            mApplication = application;
            mIntent = intent;
            mReferrer = referrer;
            mComponent = intent.getComponent();
            mActivityInfo = info;
            mTitle = title;
            mParent = parent;
            mEmbeddedID = id;
            ///赋值给mLastNonConfigurationInstances
            mLastNonConfigurationInstances = lastNonConfigurationInstances;
    

    getLastNonConfigurationInstance 获取的就是mLastNonConfigurationInstance的值

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

    3. 屏幕旋转事件

    ActivityManagerService.updateConfiguration

    @Override
        public boolean updateConfiguration(Configuration values) {
            return mActivityTaskManager.updateConfiguration(values);
        }
    

    ActivityTaskManagerService

        @Override
        public boolean updateConfiguration(Configuration values) {
          ...
        updateConfigurationLocked(values, null, false, false /* persistent */,
                            UserHandle.USER_NULL, false /* deferResume */,
                            mTmpUpdateConfigurationResult);
          ...
        }
    
    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
                boolean initLocale, boolean persistent, int userId, boolean deferResume,
                ActivityTaskManagerService.UpdateConfigurationResult result) {
                ...
                if (!deferResume) {
                    kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
                }
                ...
            
            return kept;
        }
    
    
    ensureConfigAndVisibilityAfterUpdate() -> relaunchActivityLocked(preserveWindow);
    

    relaunchActivityLocked

    try {
            
                final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
                        pendingNewIntents, configChangeFlags,
                        new MergedConfiguration(getProcessGlobalConfiguration(),
                                getMergedOverrideConfiguration()),
                        preserveWindow);
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(isTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                final ClientTransaction transaction = ClientTransaction.obtain(app.getThread(), appToken);
                transaction.addCallback(callbackItem);
                transaction.setLifecycleStateRequest(lifecycleItem);
                mAtmService.getLifecycleManager().scheduleTransaction(transaction);
    

    执行ActivityRelaunchItem

    @Override
        public void execute(ClientTransactionHandler client, ActivityClientRecord r,
                PendingTransactionActions pendingActions) {
            if (mActivityClientRecord == null) {
                if (DEBUG_ORDER) Slog.d(TAG, "Activity relaunch cancelled");
                return;
            }
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
            client.handleRelaunchActivity(mActivityClientRecord, pendingActions);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
    

    ActivityThread.handleRelaunchActivity()

        @Override
        public void handleRelaunchActivity(ActivityClientRecord tmp,
                PendingTransactionActions pendingActions) {
              
            handleRelaunchActivityInner(r, configChanges, tmp.pendingResults, tmp.pendingIntents,
                    pendingActions, tmp.startsNotResumed, tmp.overrideConfig, "handleRelaunchActivity");
      }
    

    handleRelaunchActivityInner

    private void handleRelaunchActivityInner(ActivityClientRecord r, int configChanges,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingIntents,
                PendingTransactionActions pendingActions, boolean startsNotResumed,
                Configuration overrideConfig, String reason) {
            // Preserve last used intent, it may be set from Activity#setIntent().
            final Intent customIntent = r.activity.mIntent;
            // Need to ensure state is saved.
            if (!r.paused) {
                //执行onPause
                performPauseActivity(r, false, reason, null /* pendingActions */);
            }
            if (!r.stopped) {
              // onStop
                callActivityOnStop(r, true /* saveState */, reason);
            }
            //onDestory 也是在这里保存调用onRetainNonConfigurationInstance 来保存状态的
            handleDestroyActivity(r, false, configChanges, true, reason);
    
            r.activity = null;
            r.window = null;
            r.hideForNow = false;
            r.nextIdle = null;
            // Merge any pending results and pending intents; don't just replace them
            if (pendingResults != null) {
                if (r.pendingResults == null) {
                    r.pendingResults = pendingResults;
                } else {
                    r.pendingResults.addAll(pendingResults);
                }
            }
            if (pendingIntents != null) {
                if (r.pendingIntents == null) {
                    r.pendingIntents = pendingIntents;
                } else {
                    r.pendingIntents.addAll(pendingIntents);
                }
            }
            r.startsNotResumed = startsNotResumed;
            r.overrideConfig = overrideConfig;
            //重新执行 , getLastNonConfigurationInstance 的 attach 完成赋值
            handleLaunchActivity(r, pendingActions, customIntent);
        }
    

    相关文章

      网友评论

          本文标题:ViewModel 源码解析

          本文链接:https://www.haomeiwen.com/subject/uzrtnrtx.html