转载请注明出处:
使用ViewModel共享页面内的数据:ActivityDataBus
地址:http://blog.csdn.net/qq_22744433/article/details/78195155
目录
1. 前言
Google lifecycle-component推出了Lifecycle Manager、ViewModel、LiveData、Rom等重要的类。之前也在官网看了ViewModel的介绍,但并不感冒(感觉Lifecycle Manager确实对解耦用处很大,之前也写了文章,感兴趣的可以看看。但LiveData和ViewModel,感觉并不是很实用。LiveData可以用Observable来代替,只是多了生命周期感知。ViewModel只是能在屏幕旋转的时候保存数据。)。但最近回家在火车上没事,又翻了翻之前看的内容,突然觉得ViewModel还是很有用的。可以解耦页面block或fragment之间数据/view等的相互调用。直白点说就是页面block/fragment之间需要使用对方的数据/view时,无需之间硬性的引用,只需要activity的context参数就可以获取对方的数据/view,从而进行数据交流、view访问。而页面的context是系统类型且是很容易获取的,并不存在耦合。
2. 总体概述
如果大家比较忙,没时间看下面的内容,我这里给大家做了一个概述:
使用 Viewholder方式:ViewModelProviders.of(宿主activity).get(A.class) 其中A extend ViewHolder
用处:一个activty内,任何block,adapter,view类中都可“无显式耦合”的获得彼此间的数据。举例:我们可以在activty一开始就存一个movieId的viewHolder,那么这个activty涉及的所有类中都可以使用context来获取movieId。这对于埋点等都是很好帮助的,避免了级联引用。
大致原理:ViewModelProviders.of()用于获取ViewModelProvider实例。ViewModelProvider中含有一个ViewModelStore,ViewModelStore是用来存储viewModel的(ViewModelStore内部含有map)。ViewModelStore对于宿主activity是唯一的。其实质是宿主activity中HoldFragment的一个成员变量。
3. 创建页面Bus来共享界面数据
稍微封装一下ViewModel,使用bus来管理页面内的共享数据。
我们一个activity页面肯定不止一个类。尤其是页面比较复杂的时候,一个页面有很多block。如果一个block中的某些数据/view需要另外一个block中使用,那怎么办呢?我们一般的做法就是把这个数据存成一个成员变量,set到另外一个block中。或另外一个block需要时,直接拿这个成员变量。但这样会造成,两个block之间之间耦合。设想一下,如果两个block层级比较深,那么两个block之间进行共享数据时,需要把两个block之间需要的类都进行之间耦合。
举一个我以前遇到过的例子:一个页面做完了,pm找我做页面的埋点。埋点需要页面的movieId信息,但是需要埋点的那个block中并没有movieId。并且我这个block层级很深。如果想拿到movieId,我需要从activity页面层级一层层传到我这个block中,免不了中间层级的耦合和方法的创建。当时觉得这件事真是让人头大。那时候多么需要有个像事件监听形式的eventbus