概述
viewModel是实现mvvm架构的重要组件,主要用于解决两个问题,一是减轻Actiyity/Fragment的负担,在传统的架构下Activity需要承担ui展示刷新,逻辑处理和网络回调等等任务,随着项目复杂会变得难以维护,可以用viewModel存放与界面有关的数据和网络请求等等。二是解决横竖屏旋转时Activity重新调用onCreate()方法,会丢失掉原本数据的问题。
解决第二个问题的原因是一个ViewModel的生命周期要比它所绑定的Activity长,重新创建的Activity所获得的ViewModel实例仍然是旋转之前所绑定的实例,因此数据不会丢失。
viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
通过这种方式获得ViewModel实例,下面具体看看是怎样绑定ViewModel和Activity并且实现ViewModel实例唯一性的。
首先获取这个Activity的application实例,可以看到传入第二个参数是一个工厂,它是用来解决ViewModel构造函数有参数的问题的,使用的时候继承ViewProvider.Factory并且重写create()方法,方法返回一个新实例化的ViewModel就可以了,绑定的任务不需要自己完成。
如果没传入Factory,则会检查该application是否已经有了创建工厂,并且返回或者新建后返回它。
随后创建这个Activity的ViewModelStore,发现了,是在ViewModelStore通过哈希表保存ViewModel和Activity的映射关系的。
map里面存储的key是ViewModel的规范名称,value是唯一的ViewModel实例。
ViewModel妙用(待续)
实现Activity和Fragment之间的通信
利用每个Activity的ViewModel是唯一的,可以在Fragment里面获取Activity实例,然后拿到对应的ViewModel。
实现Fragment与Fragment之间的通信
原理很简单,让两个同属于一个Activity的Fragment拿到Activity后获取同一个ViewModel就可以进行通信了。
LiveData
ViewModel需要与Activity实现双向通讯,Activity可以方便的从ViewModelStore获取自己的ViewModel实例进而操作其中的数据,但是从ViewModel与Activity的通讯就不是很方便了,如果让ViewModel持有Activity实例,那么就会因为这种引用关系导致Activity不能被及时回收导致内存泄漏的问题,偏偏这种需求是普遍存在的,例如对仓库层或者网络层的请求通常发生在ViewModel之中,结束之后需要对UI进行更新,LiveData就是用来解决这个问题的。
LiveData是一种采用了观察者模式的组件,用法是将被观察的数据用LiveData封装起来,数据的类型通过泛型来解决,在Activity传入它的LifeCycle(用于感知生命状态)以及变化后响应的接口实例即可。下面这段代码用了Lambda表达式,第二个参数是个匿名实例,即观察者的变化响应方法。
viewModel.listData.observe(viewLifecycleOwner) {
adapter = WishItemAdapter(AAAhomeApplication.context, viewModel.listData.value!!)
recycler.adapter = adapter
}
下面看一下怎么实现感知生命周期的:
首先检查是否是主线程,接着判断绑定的对象是否处于存活状态,如果均是才会进行下一步处理。
数据变化
有两个方法改变数据并且通知观察者,只能在主线程调用的setValue和没有限制的PostValue,这里以setValue为例:
在设置更新版本和更新数据以后,会调用dispatchingValue进行事件分发,在这个方法里面会获取观察者Map,这个Map的键是上面设置的匿名接口实例,值是包裹了Actiyity和匿名接口实例的包裹类,随后会遍历这个Map,依次通知所有观察者触发onChange方法。
在这个considerNotify方法中,首先检查了这个装饰器中最后更新的版本号是否小于事件的版本号,如果小于说明需要对此更新进行响应,触发onChanged方法也就是Activity中的匿名方法。
最后
以上就是怕孤单冬日为你收集整理的ViewModelLiveData的全部内容,希望文章能够帮你解决ViewModelLiveData所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复