• 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生命周期,当他被销毁并且配置没有发生改变就会清空内部的数据。

  • 相关阅读:
    探讨e.target与e.currentTarget
    JavaScript事件模型
    博客
    angular创建自定义指令的四种方式
    jqueryMobile模块整理—图标(icons)
    jqueryMobile模块整理—按钮(buttons)
    Visio 2010,如何打开多个窗口
    Ajax.ActionLink浏览器中代码解析问题
    响应式布局
    jquery的each
  • 原文地址:https://www.cnblogs.com/FCY-LearningNotes/p/14039966.html
Copyright © 2020-2023  润新知