AndroidX設計架構MVVM之ViewModel創建流程原理分析

本文基於ViewModel 2.1.0,分析在activity中ViewModel創建流程原理分析
原文

AndroidX設計架構MVVM之ViewModel創建流程原理分析
AndroidX設計架構MVVM之ViewModel生命週期分析
AndroidX設計架構MVVM之LiveDatal生命週期及數據監聽分析
AndroidX設計架構MVVM之DataBinding搭配LiveData的分析
AndroidX設計架構MVVM之DataBinding+ViewModel+LiveData

activity中的使用如下,本文不做詳細使用說明

 mViewModel = ViewModelProviders.of(this).get(getVmClass());

ViewModel的創建分兩步走:1>創建並初始化ViewModelProvider,2>根據VMClass創建ViewModel

1—創建並初始化ViewModelProvider

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

分析點3:由於傳入的factory 爲空,會走到這裏創建一個AndroidViewModelFactory,流程見代碼中的註釋。

 public static class AndroidViewModelFactory extends ViewModelProvider.NewInstanceFactory {

        private static AndroidViewModelFactory sInstance;
        @NonNull
        public static AndroidViewModelFactory getInstance(@NonNull Application application) {
            if (sInstance == null) {
                sInstance = new AndroidViewModelFactory(application);
            }
            return sInstance;
        }

        private Application mApplication;
   
        public AndroidViewModelFactory(@NonNull Application application) {
            mApplication = application;
        }

        @NonNull
        @Override
        public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
           // 判斷是否爲AndroidViewModel的子類
            if (AndroidViewModel.class.isAssignableFrom(modelClass)) {
                //noinspection TryWithIdenticalCatches
                try {
                //通過AndroidViewModel子類帶Application的構造函數創建實例
                    return modelClass.getConstructor(Application.class).newInstance(mApplication);
                } catch (NoSuchMethodException e) {
                 。。。。。。。
                }
            }
            return super.create(modelClass);
        }
    }
}

分析點4:初始化ViewModelProvider
創建或獲取已有的ViewModelStore,其實是對HashMap的簡單封裝。

 return new ViewModelProvider(activity.getViewModelStore(), factory);

//返回已有的ViewModelStore,或者重新創建
 public ViewModelStore getViewModelStore() {
          。。。。。
        if (mViewModelStore == null) {
            NonConfigurationInstances nc =
                    (NonConfigurationInstances) getLastNonConfigurationInstance();
            if (nc != null) {
               //分析點5
                // Restore the ViewModelStore from NonConfigurationInstances
                mViewModelStore = nc.viewModelStore;
            }
            if (mViewModelStore == null) {
            // 內部是一個value爲ViewModel的HashMap
                mViewModelStore = new ViewModelStore();
            }
        }
        return mViewModelStore;
    }

分析點5:這個和ViewModel的生命週期有關,可以參考ViewModel生命週期分析

2—根據VMClass創建ViewModel

進入第一步創建ViewModelProvider的get()方法,返回已有的mViewModelStore,或者創建ViewModel並保存在mViewModelStore中,再返回。也就是說一個Activity中只有一個mViewModelStore,裏邊保存了多個ViewModel

public <T extends ViewModel> T get(@NonNull Class<T> modelClass) 
        String canonicalName = modelClass.getCanonicalName();
        if (canonicalName == null) {
            throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels");
        }
        return get(DEFAULT_KEY + ":" + canonicalName, modelClass);
    }
    
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
       //key爲ViewModel 的唯一標識
        ViewModel viewModel = mViewModelStore.get(key);
       //
        if (modelClass.isInstance(viewModel)) {
            //noinspection unchecked
            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爲注意點3上創建的AndroidViewModelFactory
            viewModel = (mFactory).create(modelClass);
        }
        //存儲ViewModel
        mViewModelStore.put(key, viewModel);
        //noinspection unchecked
        return (T) viewModel;
    }

總結:
1 若activity首次加載,則ViewModelProviders通過of()方法創建了AndroidViewModelFactory和ViewModelStore,ViewModelProvider的get()方法則通過AndroidViewModelFactory創建一個ViewModel,並保存在ViewModelStore中供之後使用。
2 一個activity中只有一個ViewModelStore,ViewModelStore中保存此activity中所有ViewModel。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章