Android MVVM 源码分析

2,064 阅读5分钟
原文链接: www.jianshu.com

Android Architecture Components 源码分析

说是源码分析有点,其实就是简单的根据源码梳理一遍整体的LiveData,ViewModel和Lifecycle各个部分是如何工作的,由于本人水平有限,如果文中有错误的地方,欢迎指正。

最近这几天一直在研究官方的MVVM的实现,使用起来其实难度并不大,并且如果结合DataBinding和Dagger2 代码写的都要飞起来了,不要太好。不过我们不能仅仅停留在使用的层面上,了解每个部分是如何工作的,探索官方的实现方式,这样技术才能进步,看源码的过程中我们可以带着几个问题去探索:

  1. Lifecycle是如何感知到Activity/Fragment的生命周期的?
  2. ViewModel的生命周期是如何控制。
  3. LiveData中的数据是如何根据Lifecycle生命周期进行通知的?

预计会写三篇文章,分别介绍上面的技术关键点,首先先来介绍Lifecycle是如何感知Activity/Fragment生命周期的。

MVP时代感知生命周期的做法

众所周知,在使用MVP的时候,需要关联View的生命周期,在那个时候,生命周期的控制经历了几个阶段,从最开始官方Demo中的attach和detach,通过Activity或者Fragemnt中生命周期函数去关联挥着分离Presenter,之后又有判断View是否是Active的来决定是否去更新UI,这都是通过简单的代码控制Presenter中更新UI的动作是否执行。再后来就是RxLifecycle,也是因为Retrofit和RxJava的兴起,我们可以将Presenter中的动作变成一个流事件,这样可以根据RxJava的特性通过解除订阅的方式来控制Presenter中的更新UI的动作。这又会分为两种,根据RxJava的版本不同,RxJava1和RxJava2的解除订阅的方式不一样。当然每个写MVP的童鞋都会有自己的生命周期控制的方式,不过个人觉得还是通过RxLifecycle的方式会更好一些,因为可以细微控制到每一个生命周期函数,更进一步的,组里的一个童鞋参考Rxlifecycle的方式加进去了一些其他的生命周期,比如Dialog的显示和消失,当Dialog消失的时候取消订阅,这都是我们可以细粒化去控制的,那么在新的MVVM中的生命周期是如何实现的呢?

MVVM时代感知生命周期的做法

其实在官方的MVVM没有出现之前,相信肯定会有民间大神自己实现了的MVVM,虽然我没有找到相关的发表的文章,不过我看见过自己写代码实现的MVVM,简单来说就是有一个MVVMViewModel接口,里面包含了所有的生命周期回调的方法,然后在Activity/Fragment的各个生命周期函数中调用。这样就实现了生命周期的传递,当然了这只是简单的介绍能够实现MVVM的其中一种方式,通过函数的传递性来控制生命周期。接下来就是本文的重点了, 官方的MVVM是如何实现的生命周期控制的那?

官方MVVM感知生命周期的做法

首先如果从我们自己写的mvvm代码中是找不到生命周期控制的部分的。昨天偶然间看到了使用ContentProvider初始化你的ibrary ,作者说到的ContentProvider初始化,然后看了一眼编译过的apk


果然多了一个ContentProvider,其实生命周期的控制就是通过这个Provider来实现的。


可以看到,第一个LifecycleDispatcher.init()就是初始化生命周期控制的方法。下面的那个是整个项目的LifecycleOwner,暂时不去研究它。
接下来看初始化的时候都做了什么?


通过一个AtomicBoolean来控制初始化一次,之后就获取ApplicationContext并设置ActivityLifecycleCallback回调。这个函数其实在之前我们就使用过,比如退出app啊,或者是一些简单的打点操作的时候会使用。接下来看看DispatcherActivityCallback是什么?


构造函数创建了一个FragmentCallback,用于设置Fragment生命周期的回调,然后在onActivityCreated的时候注入了一个ReportFragment到当前的Activity。看一下Reporefragment是做什么用的。


首先将这个Fragment添加到当前的Activity中,这样这个Fragment就拥有和Activity一样的生命周期,之后在当前Fragment的生命周期函数中通过dispatch对应的Lifecycle.Event,把当前的生命周期分发到对应的LifecycleOwner中。


通过给Activity/Fragment添加额外的fragment,来获取当前的Activity/Fragment的生命周期的这种方式,在之后同样会遇到,是一种很巧妙地方式解决了生命周期的监听。在ReportFragmt中还看到了mProcessListener这个对象是用于控制整个项目的生命周期的。有兴趣的同学可以仔细看一下,并不难。

这是Activity的生命周期传递,同样的Fragment跟Activity并无区别,代码都在LifecycleDispatcher中。

总结

通过添加额外的fragment的形式来获取当前的Activity/Fragment的生命周期。然后判断当前的Activity/Fragment是否是LifecycleRegistryOwner,如果是的话,那么就分发当前的生命周期事件到当前的Owner中,这样就实现了生命周期传递。