ViewModel

参考:https://blog.csdn.net/u010072711/article/details/80035276

创建

val viewModelProvider = ViewModelProviders.of(_mActivity,viewModelFactory)val manageViewModel = viewModelProvider.get(ManageViewModel::class.java)​

源码分析ViewModel创建流程

查看ViewModelProviders类

/**     *     * @param activity     * @param factory 提供了自定义创建ViewModel的方法     * @return     */    @NonNull    @MainThread    public static ViewModelProvider of(@NonNull FragmentActivity activity,                                       @NonNull ViewModelProvider.Factory factory) {        //检测activity        checkApplication(activity);        return new ViewModelProvider(ViewModelStores.of(activity), factory);    }
  • 存在是依赖 Activity 或者 Fragment的,不管你在什么地方获取ViewModel ,只要你用的是相同的Activity 或者 Fragment,那么获取到的ViewModel将是同一个 (前提是key值是一样的),所以ViewModel 也具有数据共享的作用!

  • 每次获取ViewModel都是重新new ViewModelProvider

第一个参数ViewModelStores.of(activity)

    @MainThread    public static ViewModelStore of(@NonNull FragmentActivity activity) {        //如果你的Activity实现了ViewModelStoreOwner接口具备了提供        //ViewModelStore 的功能就直接获取返回,通常我们的Activity都不会去实现这个功能        if (activity instanceof ViewModelStoreOwner) {            return ((ViewModelStoreOwner) activity).getViewModelStore();        }        //系统为你的Activity添加一个具有提供ViewModelStore 的holderFragment        return holderFragmentFor(activity).getViewModelStore();    }

如果你的Activity实现了ViewModelStoreOwner接口具备了提供ViewModelStore 的功能就直接获取返回,通常我们的Activity都不会去实现这个功能;如果没有,则系统为你的Activity添加一个具有提供ViewModelStore 的holderFragment

总结:最终每一个Activity或者Fragment都有一个ViewModelStore,而这个ViewModelStore是存储ViewModel的

第二个参数factory,下面是自定义的ViewModelFactory kotlin写法

@Singletonclass ViewModelFactory @Inject constructor(        private val creators: Map, @JvmSuppressWildcards Provider>) : ViewModelProvider.Factory {    override fun  create(modelClass: Class): T {        val creator = creators[modelClass] ?: creators.entries.firstOrNull {            modelClass.isAssignableFrom(it.key)        }?.value ?: throw IllegalArgumentException("unknown model class $modelClass")        try {            @Suppress("UNCHECKED_CAST")            return creator.get() as T        } catch (e: Exception) {            throw RuntimeException(e)        }    }}
  • 实现 ViewModelProvider.Factory,

  • 构造传入Map, @JvmSuppressWildcards Provider>

  • create方法根据Class,从map中获取Provider,再从Provider中get得到ViewModel

解析viewModelProvider.get(ManageViewModel::class.java)

@NonNull    @MainThread    public  T get(@NonNull Class 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);    }            @NonNull    @MainThread    public  T get(@NonNull String key, @NonNull Class modelClass) {        ViewModel viewModel = mViewModelStore.get(key);​        if (modelClass.isInstance(viewModel)) {            //noinspection unchecked            return (T) viewModel;        } else {            //noinspection StatementWithEmptyBody            if (viewModel != null) {                // TODO: log a warning.            }        }​        viewModel = mFactory.create(modelClass);        mViewModelStore.put(key, viewModel);        //noinspection unchecked        return (T) viewModel;    }​

流程是:

  • 先从mViewModelStore中使用key去获取ViewModel, mViewModelStore中是使用HashMap去存储一个Activity或者FragmentViewModel的。如果获取到就返回

  • 没获取到就使用单例mFactory的create方法反射创建ViewModel,create方法的代码在上面贴出来了。

  • 使用Key存入mViewModelStore 并返回

解析ViewModelStore

public class ViewModelStore {​    private final HashMap 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);    }​    /**     *  Clears internal storage and notifies ViewModels that they are no longer used.     */    public final void clear() {        for (ViewModel vm : mMap.values()) {            vm.onCleared();        }        mMap.clear();    }}

大概内容是:

一个 HashMap用存储ViewModel。提供get,put,clear三个方法。 上面说了ViewModelStore是每一个Activity或者ViewModel都有一个的,当Activity或者Fragment销毁的时候就会调用clear方法了。

  • ViewModelStore被HolderFragment创建和持有

  • 当我们要给Activity或者Fragment创建ViewModel的时候,系统就会为Activity或者Fragment添加一个HolderFragmentHolderFragment中会创建持有一个ViewModelStore

结合Dagger2

​    @Binds    @IntoMap    @ViewModelKey(HealthViewModel::class)    abstract fun bindHealthViewModel(healthViewModel: HealthViewModel): ViewModel​    @Binds    @IntoMap    @ViewModelKey(MainViewModel::class)    abstract fun bindMainViewModel(mainViewModel: MainViewModel): ViewModel​    @Binds    abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
  • @Bind 和 @Provider的作用相差不大,区别在于@Provider需要写明具体的实现,而@Binds只是告诉Dagger2谁是谁实现的

  • @IntoMap 则可以让Dagger2将多个元素依赖注入到Map之中

  • @ViewModelKey(MainViewModel::class) Dagger2会根据这些信息自动生成一个关键的Map。key为ViewModel的Class,value则为提供ViewModel实例的Provider对象,通过provider.get()方法就可以获取到相应的ViewModel对象

上面ViewModelFactory的分析有,看到他的构造是map,而通过dagger2 的@IntoMap @ViewModelKey()可生成一个map,正好为ViewModelFactory的创建提供参数,同时发现在ViewModelProviders.of(this)中发现默认的factory每次传入都是单例的,所以在ViewModelFactory用@Singleton来修饰

总结ViewModel的创建流程是

  • new ViewModelProvider,传入两个参数,一个是ViewModelStore,一个是ViewModelProvider.Factory,

  • ViewModelStore由,当要给Activity或者Fragment创建ViewModel的时候,系统就会为Activity或者Fragment添加一个HolderFragmentHolderFragment中会创建持有一个ViewModelStore

  • 当ViewModelProvider.get()时,先查看ViewModelStore是否存储有,有则返回,无则通过Factory来创建一个

 

 

更多相关文章

  1. Android前端通过Http协议与J2EE后端数据交互。工具eclipse、MySQ
  2. android使用sharedPreferences()方法读写文件操作
  3. Android实现发短信与打电话的功能
  4. 2.4.7 选项卡的功能和用法
  5. Android:Activity中onCreate方法的参数及用途
  6. 最新Android 7.1.1 截屏方法
  7. android实现多线程断点续传功能
  8. Android应用程序四种数据存取方法总结
  9. traceview的使用方法

随机推荐

  1. Android上面的百度地图使用步骤
  2. Android(安卓)studio gradle配置完整版
  3. android textview设置字体的行距和字间距
  4. Android搭建开发环境
  5. Android(安卓)studio 点击按钮跳转到新的
  6. Android(安卓)的recovery模式分析
  7. Android(安卓)Studio中的六种依赖
  8. Android(安卓)Studio中SVN安装与使用
  9. Android高效加载大图、多图解决方案,有效
  10. 35 个你必看的 Android(安卓)库