前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LiveDate和LifeRegistry的协同操作

LiveDate和LifeRegistry的协同操作

作者头像
我就是马云飞
发布2018-02-05 11:00:00
8720
发布2018-02-05 11:00:00
举报
文章被收录于专栏:我就是马云飞我就是马云飞

前言

这个是Android Architecture Components(简称AAC)的第三篇,之前的两篇 文章分别介绍了Lifecycle和ViewModel的生命周期,这篇主要讲的就是最开始提出的第三个问题LiveData数据的控制。

简单案例

先列举一个简单的例子,看看如何使用的:

在ViewModel中有LiveData的成员变量,然后添加一个观察者。在ViewModel中

在ViewModel中就是拥有一个成员变量,加上对应的get方法,修改数据的时候直接使用setValue更新,这样就会弹出一个Toast。

使用起来并不难,但我们的目的是了解如何实现的。

案例分析

关于上文的例子,从三个部分开始分析,一是添加观察者的时候,二是生命周期的控制,三是设置数据的时候。

添加观察者

  1. 先判断一下LifecycleRegistry当前的状态,如果是DESTORYED的话,就直接返回。
  2. 之后是将LifecycleOwner和创建Observer封装到LifecycleBoundObserver中。
  3. 从当前的Oberver集合中查找没有传入的Observer对应的包装类,如果有则返回,没有则添加。
  4. LifecycleRegistry添加包装之后的LifecycleBoundObserver观察者。
  5. 更新下当前的包装类的状态。

这里需要理解并记住的是LifecycleBoundObserver是一个拥有真正回调Observer和LifecycleOwner的封装类。

在LifecycleRegistry中添加观察者,这个LifecycleRegistry是在Activity/Fragment中创建的成员变量。

  1. 确定初始时LifecycleBoundObserverd的状态,这里大部分的情况都是INITIALIZED,除非把之前的observe写在onDestory中,不过估计一般没人这么写。
  2. 将传入的LifecycleBoundObserver和确定的状态封装到一个statefulObserver。在这个过程中会对observer进行一定转化,将其改变成另一种LifecycleObserver,然后再使用的时候会通过反射去调到实际需要的方法。
  3. 将封装过的statefulObserver和传入的observer添加到当前的一个map中进行保存,如果之前已经添加过的话,就直接返回旧的,没有的话再放入,返回null。
  4. 判断是否可以重入,来决定是否进行同步,这里的parentState暂时先不考虑,等最后的时候再分析。
  5. 其中while循环的部分是为了修改刚添加进去的ObseverWithState中state的状态。
  6. sync方法是事件传递的关键,在之后也会用到,就先不分析。

接下来看一下当生命周期变化的时候会发生什么?

生命周期改变

根据第一篇文章中我们可以知道当应用的生命周期变化的时候,会发送对应的生命周期事件到LifecycleRegistry的handleLifecycleEvent方法中进行处理,这里先简单的分析下逻辑。

首先设置当前的LifecycleRegistry中的mState值,之后执行sync方法

这里先判断一下是否可以进行同步,判断的条件是当前map中的oberver数量和状态,之后会根据当前的mObserverMap中保存的observer的状态和当前的Registry的状态进行比较,来决定是进行正推计算还是反推计算。先以正推计算为例:

把当前的mObserverMap中的数据进行迭代,判断状态之后执行observer.dispatchEvent()方法,来同步Observer

这里会先设置当前的Observer的状态,之后会调用Observer的onStateChanged方法,这个方法会经过一系列的变化,通过反射,最终调到LiveData中的LifecycleBoundObserver的onStateChage()方法

这两个方法最主要的作用就是判断当前的LifecycleOwner是否是active状态。如果是active状态的话就刷新数据。

数据更新

上面正好讲到刷新数据,我们来继续说一下当setvalue的时候发生了什么:

可以看到将成员变量mData赋值 ,之后也是调用了相同的dispatchingValue方法

这里的关键函数就是considerNotify,如果是通过setValue方法进行更新的话,会更新所有的observer,如果是通过handleLifecycleEvent方法进行更新的话,那么只会更改当前的observer。

首先会先检查当前的observer的active,之后会检查observer的owner的状态是否是可用的,再判断当前的版本。最后进行更新数据。

小结

到这里其实整体的生命周期事件的观察和传递,同步和更新,修改数据,都已经简单的介绍完毕了,单单拿出来一个部分其实并不难理解,主要需要明白并记住的就是LifecycleRigestry的mState、Event、ObserverWithState的mState和LifecycleBoundObserver的active。事件的来源只有一种就是handleLifecycleEvent,最终的目的地就是为了修改ObserverWithState的mState和LifecycleBoundObserver的active。

整体流程分析

每一个小部分的功能都有所了解的之后,让我们尝试下梳理最上面的案例中整个事件的传递。这里添加订阅者是在onCreate方法中。先上个我自己画的图,方便理解。

这个是我自己梳理的整体的事件流程和刷新的图。根据这个图来介绍下执行的流程。

  1. 由于上面的案例是在onCreate中订阅的,那么最开始先执行的应该是addObserver,这个时候会把LifecycleRegistry的mState(下文简称RS)置为INITIALIZED。并向observerMap中添加封装过的ObserverWithState,其中的mState(下文简称OS)为INITIALIZED。不执行同步方法。
  2. Activity启动,传递过来第一个生命周期事件ON_CREATE,通过getStateAfter计算之后的State为CREATED赋值给RS,判断状态决定执行正推计算,OS的当前值为INITIALIZED,更改LifecycleBoundObserver的active(下文简称active)值为false。OS修改为CREATED。
  3. 事件ON_START,RS为STARTED,正推计算,OS当前值为CREATED,更改active为true。OS修改为STARTED。
  4. 事件ON_RESUME,RS为RESUMED,正推计算,OS当前值为STARTED,更改active为true。OS修改为RESUMED。
  5. 事件ON_PAUSE,RS为STARTED,反推计算,OS当前值为STARTED,更改active为true。OS修改为STARTED。
  6. 事件ON_STOP,RS为CREATED,反推计算,OS当前值为CREATED,更改active为false。OS修改为CREATED。
  7. 事件ON_DESTROY,RS为DESTROYED,反推计算,OS当前值为DESTROYED,更改active为false。OS修改为DESTROYED。

整体事件流程就是这样,通过感知Activity/Fragment的生命周期,然后分发到LifecycleRegistry中进行处理,根据当前的状态来修改保存的ObserverWithState的mState,然后修改LifecycleBoundObserver的active决定数据是否可以更新。

上面的状态都是作者根据最开始的案例断点调试得出的结论,值得注意的就是因为有Application也就是ProcessLifecycleOwner的干扰,调试的时候要区分好LifeRegistry,第二个注意的就是mState的值,因为有两个mState,经常会需要进行比较,来决定同步。

总结

至此,整个Android Architecture Components架构中所有的源码都过了一遍了, 主要的难点就是在handleLifecycleEvent()和Sync()两个方法。总体的分析下整个架构:

个人认为主要分为三个部分:

第一部分:生命周期的感知包括系统生命周期的感知。其中有使用的类和技巧有,通过注册ContenProvider进行项目的初始化,通过添加Fragment来获取宿主的生命周期。通过给Application和Activity添加生命周期的回调,来进行Fragment的初始化和生命周期的感知。

相关的类包括: LifecycleRuntimeTrojanProvider 用于进行初始化init操作LifecycleDispatcher 用于进行生命周期分发处理ProcessLifecycleOwner 应用生命周期控制 ,、 ReportFragment 添加的Fragment 用于感知宿主生命周期

第二部分:ViewModel生命周期的控制。同样使用了添加Fragment来感知宿主的生命周期,通过一个HoldFragment来持有一个ViewModelStore保存当前宿主的所有ViewModel,通过工厂模式反射获得ViewModel对象。

相关的类包括: ViewModelViewModelProvider ViewModel的提供者ViewModelStore 用于保存ViewModelHolderFragment 添加的Fragment 用于感知宿主生命周期等。

第三部分:LiveData和LifecycleRegistry的协同操作。这里使用了两个枚举对象来概括整体的生命周期,通过Event的传递来改变当前的Lifecycyle的状态,同时更新当前的Observer是否处于活动状态。个人认为整个项目中的关于Observer的三个封装类是整个项目的骨架,State和Event就是流动血液,而HandleLifecycleEvent和Sync两个方法就是整个项目的灵魂。

相关的类包括: LiveData 数据模型LifecycleOwner 生命周期持有者LifecycleRegistry 用于控制生命周期ObserverWithState 保存Observer和对应的状态LifecycleBoundObserver 保存Observer和LifecycleOwnerReflectiveGenericLifecycleObserver 反射调用的相关类

学习收获

这不是我第一次去深入的研究系统的源码了,不过每一次看源代码真的都能带来新的收获和想法。在学习AAC的过程中,最大的收获感觉还是对AAC项目的熟悉,能够清楚的知道每一个类,每一个方法,每一个成员变量的作用,是用来做什么的,什么起作用。当我看到它们的类名就能够知道他们是做什么的,这种熟悉感,我觉得是最大的收获。其次是在研究源码过程中一些心得体会,遇到难度高的地方的时候适当的放松,真的会有助于解决问题,我这里有好几个关键点都是我下楼散步的时候想到的为什么。

最后想要说的就是对于知识的渴望程度,或者说对于知识的了解程度,我觉得这种概念适用于所有领域,以AAC这个框架为例

  1. 会使用,能够写代码
  2. 知道原理,了解源代码是什么实现的,知道每一个部分的原理,功用。
  3. 能够修改,在原有的基础上进行修改,使其变得更优或者更适用于自己。

目前在学习第三方框架的时候,都在遵循着三点,争取都能够达到第二层次,部分简单的项目可以实现第三层次。这好比练武功,从登堂入室,再到烂熟于心,再到推陈出新。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-10-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 我就是马云飞 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 添加观察者
  • 生命周期改变
  • 整体流程分析
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档