ViewModel构造

ViewModel

ViewModel的构造

viewModel = new ViewModelProvider(this).get(UserViewModel.class);

ViewModelProvider的构造

////////////////////
//   field      ///
//////////////////
    private final Factory mFactory;
    private final ViewModelStore mViewModelStore;
    private static final String DEFAULT_KEY =
            "androidx.lifecycle.ViewModelProvider.DefaultKey";
////////////////////
//   构造方法    ///
//////////////////

    public ViewModelProvider(@NonNull ViewModelStoreOwner owner) {
        // 如果传入的生命周期绑定对象,实现了HasDefaultViewModelProviderFactory则返回其实现的getDefaultViewModelProviderFactory()方法返回的对象,否则就返回NewInstanceFactory.getInstance()
          this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory
                    ? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory()
                    : NewInstanceFactory.getInstance());
    }

******************************************************
*** Fragment实现了该接口,分析fragment的该实现方法    ***
******************************************************
    @NonNull
    @Override
    public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
        if (mFragmentManager == null) {
            throw new IllegalStateException("Can't access ViewModels from detached fragment");
        }
        if (mDefaultFactory == null) {
            mDefaultFactory = new SavedStateViewModelFactory(
                    requireActivity().getApplication(),
                    this,
                    getArguments());
        }
        return mDefaultFactory;
    }

  // 可以看出来SavedStateViewModelFactory继承自ViewModelProvider的一个内部类,并且封装了一个AndroidViewModelFactory  
public final class SavedStateViewModelFactory extends ViewModelProvider.KeyedFactory{
////////////////////
//   field      ///
//////////////////

    private final Application mApplication;
    private final ViewModelProvider.AndroidViewModelFactory mFactory;
    private final Bundle mDefaultArgs;
    private final Lifecycle mLifecycle;
    private final SavedStateRegistry mSavedStateRegistry;


   public SavedStateViewModelFactory(@NonNull Application application,
            @NonNull SavedStateRegistryOwner owner,
            @Nullable Bundle defaultArgs) {
        mSavedStateRegistry = owner.getSavedStateRegistry();
        mLifecycle = owner.getLifecycle();
        mDefaultArgs = defaultArgs;
        mApplication = application;
        mFactory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
    }

}






     public ViewModelProvider(@NonNull ViewModelStoreOwner owner, @NonNull Factory factory) {
        this(owner.getViewModelStore(), factory);
    }
    

    public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) {
        mFactory = factory;
        mViewModelStore = store;
    }

///////////////////////////////
//   构造ViewMdoel的方法    ///
/////////////////////////////
    public <T extends ViewModel> T get(@NonNull Class<T> modelClass) {
        // 拿到viewModel实体类的规范类名
        String canonicalName = modelClass.getCanonicalName();
        if (canonicalName == null) {
            throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels");
        }
        return get(DEFAULT_KEY + ":" + canonicalName, modelClass);
    }

    @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.
            }
        }
        // fragment的mFactory的是上述中封装的SavedStateViewModelFactory继承自KeyedFactory。KeyedFactory继承自OnRequeryFactory并实现了Factory接口
        if (mFactory instanceof KeyedFactory) {
            //此处的KeyedFactory是指静态抽象类不是接口
            viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);
        } else {
            viewModel = (mFactory).create(modelClass);
        }
        mViewModelStore.put(key, viewModel);
        return (T) viewModel;
    }
//////////////////////////分析SavedStateViewModelFactory的create方法//////////////////

    private static final Class<?>[] ANDROID_VIEWMODEL_SIGNATURE = new Class[]{Application.class,
            SavedStateHandle.class};
    private static final Class<?>[] VIEWMODEL_SIGNATURE = new Class[]{SavedStateHandle.class};


 @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        // ViewModelProvider calls correct create that support same modelClass with different keys
        // If a developer manually calls this method, there is no "key" in picture, so factory
        // simply uses classname internally as as key.
        String canonicalName = modelClass.getCanonicalName();
        if (canonicalName == null) {
            throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels");
        }
        return create(canonicalName, modelClass);
    }

    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull String key, @NonNull Class<T> modelClass) {

        // 判断modelClass是否属于是AndroidViewModel的子类
        boolean isAndroidViewModel = AndroidViewModel.class.isAssignableFrom(modelClass);
        Constructor<T> constructor;
        if (isAndroidViewModel) {
            constructor = findMatchingConstructor(modelClass, ANDROID_VIEWMODEL_SIGNATURE);
        } else {
            //构造方法的参数为有一个SavedStateHandle类参数的构造方法
            constructor = findMatchingConstructor(modelClass, VIEWMODEL_SIGNATURE);
        }
        // 如果该类没有只有一个SavedStateHandle参数的构造方法则使用AndroidViewModelFactory的构造方法,如果该类继承自AndroidViewModel则会调用AndroidViewModelFactory带Application参数的构造方法,否则就返回无参构造方法
        
        // doesn't need SavedStateHandle
        if (constructor == null) {
            return mFactory.create(modelClass);
        }

        SavedStateHandleController controller = SavedStateHandleController.create(
                mSavedStateRegistry, mLifecycle, key, mDefaultArgs);
        
        // 如果该构造函数doesn't need SavedStateHandle则该使用该构造函数构造时传入从controller拿到的SavedStateHandle参数
        try {
            T viewmodel;
            if (isAndroidViewModel) {
                viewmodel = constructor.newInstance(mApplication, controller.getHandle());
            } else {
                viewmodel = constructor.newInstance(controller.getHandle());
            }
            viewmodel.setTagIfAbsent(TAG_SAVED_STATE_HANDLE_CONTROLLER, controller);
            return viewmodel;
        } catch (IllegalAccessException e) {
            throw new RuntimeException("Failed to access " + modelClass, e);
        } catch (InstantiationException e) {
            throw new RuntimeException("A " + modelClass + " cannot be instantiated.", e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException("An exception happened in constructor of "
                    + modelClass, e.getCause());
        }
    }

create方法先拿到要构造的套构造的ViewModel类的规范类名,然后利用反射找出构造函数,接着完成ViewModel的构造并返回,要想使用ViewModel带
Applic构造方法该ViewModel必须继承自AndroidViewModel。

////////////////////结束//////////////////////////

我们上边介绍的是ViewModel的构造

ViewModel

为什么Viewmodel可以在手机旋转后导致activity销毁后仍可以恢复其中的数据?
ViewModelStoreOwner是一个接口activity实现,activity保存并持有viewmodelstore,viewmodelstore内部维护了一个hashmap<String,Viewmodel>
当我们使用viewmodelProvider(viewmodelstoreOwner).get(class)的时候会从viewmodelStroe中取出相应的key为viewmodel.classs name + defaValue 的viewmodel。ActivityThread.performDestroyActivity(会调度执行onDestory()方法)会被执行,在ActivityThread.performDestroyActivity中activity会调用retainNonConfigurationInstances()在该方法中会执行onRetainNonConfigurationInstance()在该方法里getLastNonConfigurationInstance()拿到NonConfigurationInstances(该类内部保存了viewModelStore)改值返回到retainNonConfigurationInstances()中并保存在ActivityThread中。下次 Activity 重建时,由 ActivityThread.performLaunchActivity 方法中调用Activity.attach 方法,再将 NonConfigurationInstances 实例传给重建后的 Activity。现在的问题是Viewmodel现在由activity关了,谁来决定他的销毁,原来viewmodel在创建的时候就开始观察activity生命周期,当他被销毁并且配置没有发生改变就会清空内部的数据。

posted @ 2020-11-25 23:47  沙雕货  阅读(294)  评论(0编辑  收藏  举报