jetpack之lifecycle使用及源码详解

1、介绍:

lifecycle是一个能监听activity和fragment生命周期的库,它可以帮助我们将所有依赖于生命周期的业务逻辑剥离出去,从而能使代码变得更精简和有条理性,也可以有效地避免内存泄漏风险。

2、场景

lifecycle的使用场景非常广泛,凡是跟生命周期相关的都可以用得上它,比如定位的开始和取消、Handler消息移除、动画绘制的暂停和恢复、与viewmodel配合使用等等一些常用的操作。

以viewmodel为例,我们先来看下我示例中没有使用lifecycle之前是什么样子的:

homeFragment类:

HomeViewModel类:

从上面两张图可以看出,viewmodel的一个调用方式都非常依赖于activity和fragment的生命周期的,这种看似没什么问题,但在实际项目中业务逻辑地复杂化,activity/fragment生命周期方法会大量充斥着与viewmodel关联的代码,同时也大大增加了两者之间的耦合度,因此便是lifecycle用武之地的时候了。

lifecycle用法比较简单,共两步:

1、实现LifecycleObserver,你也可以把它理解为观察者,你哪个逻辑类依赖于生命周期,就在哪个类里去实现LifecycleObserver接口,我这里是单独创建了个viewmodel基类去实现这个接口,如下图:

从上图大家应该看出来了,这个类里面的方法是不是跟activity的生命周期很像?没错,它就是跟生命周期动作进行对应的,至于为什么,后面会一步一步去分析,但需要主要是,这些方法并不是直接生成的,而是手动创建的,意思就是你想让某个方法在哪个生命周期方法里执行,你就在这个方法上面加上注解,指定对应生命周期名就好了,我们看下OnLifecycleEvent这个注解:

从上图注解中我们看到RetentionPolicy.RUNTIME就可以得知它是运行时注解,我们至少大致可以推断它里面是通过java放射来拿到这个注解来找到各个方法的,接下来我们看下Lifecycle.Event里面都有哪些元素:

从上图看到,它里面除了on_any外剩余六个都是和activity生命周期一样

然后将baseViewModel去继承ViewModelObserver,之前BaseviewModel是直接继承ViewModel的,是viewmodel层基类,专处理viewmodel公共逻辑,现在因为单独新增了监听生命周期的ViewModelObserver,所以便改成继承它,如下图:

2、添加关联,也就是将观察者LifecycleObserver实现类添加到Lifecycle类里,形成观察者与被观察者之间的关系,因为是观察activity/fragment生命周期动作,所以这代码需要在activity和fragment里加getLifecycle().addObserver(mViewModel)这段代码进行关联,如下图:

BaseVmActivity基类:

BaseVmFragment基类:

因为ComponentActivity和fragment都实现了LifecycleOwner这个接口,所以我们是直接可以拿到LifecycleOwner接口里面的getLifecycle()方法的,所以我们通过getLifecycle().add()然后将观察者添加进去就可以形成关联了,我们之前在ViewModelObserver类里的各个注解的生命周期方法里都加了log日志,现在我们运行起来看下日志:

上图是页面进来后再进行跳转操作后的第一个页面所留下的日志,说明这个生命周期是对的

下面我们开始将homeFragment和homeViewmodel类进行调整下,我们现在就不用在某个生命周期方法里再调用homeViewmodel里的方法去请求数据,也不需要在activity暂停或者销毁的时候再调用homeViewmodel里面的一些释放或者关闭等一些操作,现在这些操作都在homeViewmodel类里进行独立完成了,因为它里面有生命周期方法了,如下图:

homeFragment类

homeViewmodel类

3、源码分析:

从上可以看出,Lifecycle用起来确实非常方便,包括LiveData以及基于LiveData进行封装的LiveDataBus它里面都离不开Lifecycle,那它里面到底是怎么实现的?LiveData我下期会单独在写一篇文章

我们再来回顾下前面这段代码:

getLifecycle().addObserver(mViewModel);

前面有讲到,getLifecycle()是来自LifecycleOwner接口的实现方法,返回Lifecycle对象

LifecycleObserver:被前面ViewModelObserver类实现,我们可以把它当成观察者

LifecycleOwner:被ComponentActivity和Fragment实现,我们可以把它当成被观察者

我们先看下addObserver()里面的源码:

我们再点击左边箭头继续进入:

上图我们可以看到,最开始是给它设了一个初始状态值INITIALIZED,因为刚开始不可能是DESTROYED状态,然后将初始状态保存到ObserverWithState对象中,然后将初始状态进行分发,之后在进行一个初始同步化操作,我们可以看到INITIALIZED所属的一个State枚举,如下图:

然后我们发现State枚举所在的Lifecycle类里面还有一个Event枚举:

没错,就是我们前面添加注解的一个生命周期状态值,那它们之间有着什么样的联系?接着我们再来看下ComponentActivity类,也是AppCompatActivity的父类:

然后我再进到onCreate方法:

再继续进入:

从上图可以看出,先是通过activity获得了一个fragment管理器,然后在管理器里面新创建了一个空的ReportFragment,也就是在activity里新建了一个空的fragment,我们看下该fragment的生命周期方法:

看到这我们似乎明白了一些东西,它之所以创建一个空的fragment,就是想通过该fragment的生命周期进行对应的状态分发操作,接着我们继续追踪它是如何进行分发的:

我们继续追踪:

从上图我们就可以看到States和Events它们之间的一个关系了

 

接着我们再继续看下一步的操作:

如果同步则返回,没同步则进行同步操作,接着我看sync()方法实现:

如果最开始储存的state初始值是INITIALIZED,而我们当前生命周期状态mState是on_create,那么mState.compareTo(newest.getValue().mState) > 0,所以正向推,执行forwardPass()方法。如果当前mState状态是on_stop状态,存储的state状态是STARTED,那么mState.compareTo(newest.getValue().mState) < 0,反向推,执行backwardPass()方法,如下图:

 

从上可以看出,先是需要从map迭代器去一个一个去遍历拿出来,因为存在多个观察者添加的情况,拿出来后再做同步处理,如下图:

拿到同步后的状态后,紧接着进行分发:

从上我们可以看到,mLifecycleObserver它是一个LifecycleObserver接口,还记不记得我们的ViewModelObserver观察者类就是实现它的?而构造参数observer就是我们最开始在addObserver()方法里传过来的ViewModelObserver实例,接着我们看下lifecycleEventObserver方法里的实现:

 

没错,经过前面的一系列判断,最终它还是返回ReflectiveGenericLifecycleObserver类,拿到后并调用了ReflectiveGenericLifecycleObserver里面的onStateChanged方法,我先来看下这个类里面的具体实现:

看备注信息就能明白,它是依赖于反射的内部实现类,也就是说最终的核心实现就在这个类,wrapped实际上就是viewModelObserver观察者实现类,我们再进到getInfo()方法里去看下:

从方法中可以看出来,它是通过反射的getDeclaredMethods方法拿到viewModelObserver观察者类里所有的方法集合,然后通过遍历拿到每个方法上的注解和参数,并根据参数数量去指定相应的类型,然后存储并返回

接下来我们拿到信息后,进到invokeCallBacks()看下实现:

从中我们可以看到,最终再通过反射调用了我们ViewModelObserver类的注解方法,所以我们才能实时监听到activity/fragment生命周期的动作。

4、自定义activity

我们也可以自定义activity去实现LifecycleOwner,但需要通过LifecycleRegistry实例在生命周期方法里去手动地进行分发,如下图:

观察者实现类还是用我们之前的ViewModelObserver,我们看到handleLifecycleEvent这个方法是不是很熟悉?没错,就是我们前面分析源码时的一个分发操作,好我们运行看下日志:

上面日志是进入此页面再返回的一个动作,所以日志结果也是正常的。

除了了用handleLifecycleEvent之外,还可以使用markState方法,我们看下源码:

是不是最终又到了我们前面分析源码时看到的moveToState方法里来了?不过handleLifecycleEvent传的lifecycle.Event,而markState是传的lifecycle.State,而lifecycle.Event是直接对应当前的生命周期,所以直接传对应的就好了,而lifecycle.State则需要根据当前的lifecycle.Event来获得下一个状态便可,所以在handleLifecycleEvent方法就是通过getStateAfter(event)来获得的,如下图:

最后我们再看下调整后的代码:

好了,本文到此结束,篇幅有点长,感谢大家的阅读,希望对大家有用!

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值