LifeCycles 的简单理解和使用
LifeCycles
1、Lifecycles 简介
Lifecycles 即生命周期,属于 Jetpack 架构组件之一的 Lifecycles 组件是可以为其它组件提供生命周期感知能力的一个组件
,而具备了生命周期感知能力的组件就叫生命周期感知组件
。
那么什么是生命周期感知能力呢?
我们知道四大基础组件有生命周期,能感知这些生命周期的组件就具备了生命周期感知能力,所以我认为以前我们使用的 MVP 模式中的 Presenter 如果它通过接口等方式间接获得了 Activity 的生命周期,它也算是一个生命周期感知组件,但是这种获取生命周期的方式和 Lifecycles 比起来还是太 low 了,我们接着对比传统生命周期感知方式,聊一聊为什么使用 Lifecycles 组件。
2、为什么需要 Lifecycles 组件 ?
我们知道,一个 Android App 之所以能够完成一系列复杂任务,都是基于各个基础组件之间的密切配合,我们熟知的四大组件(Activity、Service、Broadcast、Content Provider
)是有生命周期的,并且 Android 的操作系统层或者 FrameWork 框架层会为其提供相应的回调,以便程序在不同的状态下做相对正确的事;
而普通的组件或者我们自己开发的一些组件就没有这个待遇了,我们通常需要在合适的时候,手动将这些第三方组件的状态控制方法,诸如启动/关闭/注册/拆除等,添加到具备生命周期的组件的回调中去才能使它们正确工作。
然后,随着时间推移版本迭代,引用的第三方组件越来越多,你的代码逐渐变成了这样
override fun onStart() {
a.init()
b.start()
c.initialize()
...
}
...
override fun onStop(){
if(a!=null) a.remove()
if(b!=null&&b.c!=null) {
b.c.tearDown()
b.stop()
}
c.stop()
...
}
你可能会在 Presenter 中完成这一系列操作,但这其实没有解决根本问题:随着第三方组件越来越多的引入,你的 Presenter 也越来越难以维护和测试。而且还可能出现内存泄露的情况
override fun onStart() {
Util.checkUserStatus { result ->
// 此回调可能在 onStop 之后被调用
if(result){
b.start()
}
}
}
...
override fun onStop(){
b.stop()
}
2.1、自定义方法举例
也许有点抽象,举个例子说明一下,比如有个需求,需要在一个界面比较频繁更新地理位置信息。当Activity走了onstop之后,你应该也要暂停更新地理位置,或者当Activity走destroy后,你要释放一些资源。下面用一些代码实例解析一下:
class MyLocationListener {
public MyLocationListener(Context context, Callback callback)
{
// ...
}
void start() {
// 开始连接位置服务
}
void stop() {
// 停止连接位置服务
}
void destroy(){
//释放资源
}
}
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
@Override
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, new Callback(){
//回调更新UI
});
}
@Override
public void onStart() {
super.onStart();
myLocationListener.start();
//绑定actiivty的onStart周期函数
}
@Override
public void onStop() {
super.onStop();
myLocationListener.stop();
//绑定actiivty的onStop周期函数
}
@Override
public void onDestroy() {
super.onDestroy();
myLocationListener.destroy();
//绑定actiivty的onDestroy周期函数
}
}
随着第三方组件越来越多的引入,越来越难以维护和测试
3、 Lifecycles 组件 的使用
- 1、实现
LifecycleObserver
接口 - 2、
LifeCycle
的addObserver
方法添加观察者 - 3、通过
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
注解方式给方法加上注解,就实现了生命周期的调用
class MyLocationListener implements LifecycleObserver{
public MyLocationListener(Context context, Callback callback) {
// ...
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
void start() {
// 开始连接位置服务
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void stop() {
// 停止连接位置服务
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
void destroy(){
//释放资源
}
}
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
@Override
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, new Callback(){
//回调更新UI
});
getLifecycle().addObserver(myLocationListener);
}
}
有关生命周期管理 Google说了要在ViewModel中处理数据逻辑 但不包括网络请求,尽量不要传递Activity的上下文和View的上下文避免内存泄漏,尽量不要再Activity或者Fragment中处理数据和逻辑,保持干净。当之后学完ViewModel和LiveData 还有DataBinding之后,就会发现,UI显示的处理和异常的处理真的方便。
4、 Lifecycles 组件 原理
看下Fragment
和LifecycleOwner
、LifecycleObserver
、Lifecycle
之间的类关系图。
Lifecycle
组件成员Lifecycle被定义成了抽象类,LifecycleOwner
、LifecycleObserver
被定义成了接口;Fragment
实现了LifecycleOwner
接口,该只有一个返回Lifecycle对象的方法getLifecyle()
;Fragment
中getLifecycle()
方法返回的是继承了抽象类Lifecycle的LifecycleRegistry
。LifecycleRegistry
中定义嵌套类ObserverWithState
,该类持有GenericLifecycleObserver
对象,而GenericLifecycleObserver
是继承了LifecycleObserver
的接口。Lifecycle:Lifecycle
是一个持有组件生命周期状态(如Activity或Fragment)的信息的类,并允许其他对象观察此状态。Event
:从框架和Lifecycle类派发的生命周期事件。这些事件映射到活动和片段中的回调事件State
:由Lifecycle对象跟踪的组件的当前状态。
4.1、LifeCycle中两个重要的接口
LifecycleOwner
(重要)Lifecycle持有者
- 实现该接口的类持有生命周期(Lifecycle对象),该接口的生命周期(Lifecycle对象)的改变会被其注册的观察者
LifecycleObserver
观察到并触发其对应的事件。
LifecycleObserver
(重要)Lifecycle观察者
- 实现该接口的类,通过注解的方式,可以通过
LifecycleOwner
类addObserver(LifecycleObserver o)
方法注册,被注册后,LifecycleObserver
便可以观察到LifecycleOwner
的生命周期事件。
4.1.1、LifecycleOwner(生命周期持有者接口)
官网介绍:LifecycleOwner是一个单一的方法接口,表示该类有一个Lifecycle。它有一个方法,getLifecycle()这个方法 必须由这个类来实现。如果您试图管理整个应用程序进程的生命周期,请参阅 ProcessLifecycleOwner。该接口从各个类(如Fragment和AppCompatActivity)抽象生命周期的所有权,并允许编写与它们一起工作的组件。
- 任何自定义应用程序类都可以实现LifecycleOwner接口
- 实现LifecycleObserver的组件与实现LifecycleOwner的组件无缝协作,因为所有者可以提供生命周期,观察者可以注册以观看
简单来说,LifecycleOwner
就是一个接口,谁继承了它,就持有了lifecycle
对象。然后就可以调用getLifecycle
()方法获取继承了抽象类Lifecycle的LifecycleRegistry
,然后调用 addObserver(@NonNull LifecycleObserver observer)
方法来注册监听。
这样,该接口的生命周期(Lifecycle对象)的改变会被其注册的观察者LifecycleObserver观察到并触发其对应的事件。
注意:
Support Library 26.1.0 及其以后的版本,Activity 和Fragment 已经实现了LifecycleOwner 接口,所以,我们可以直接在Activity 和Fragment中使用getLifecycle()方法来获取lifecycle对象,来添加观察者监听。
4.1.2、LifecycleObserver(生命周期观察者接口)
LifecycleObserver
是一个观察者接口,实现了它,可以通过注解或者继承的方式,来管理声明周期的监听。只要在持有lifecycle
的类中注册了它,当声明周期发生变化时,它就能收到,进行我们自定义的操作。
两种实现方式:
- 实现
DefultLifecyceObserver
接口,然后重写里面生命周期方法; - 直接实现
LifecycleObserver
接口,然后通过注解
的方式来接收生命周期的变化;
4.2、时序图
对于Fragment、Lifecycle、LifecycleOwner、LifecycleObserver的关系有了一定了解后,可以看一个更直观的图,也就是下面的时序图:
- 我们在
Fragment
(AppCompatActivity也一样)中调用getLifecycle
()方法得到LifecycleRegistry
对象,然后调用addObserver
()方法并将实现了LifecycleObserver
接口的对象作为参数传进去。这样一个过程就完成了注册监听的过程。 - 后续就是
Fragment
生命周期变化时,通知LifecycleObserver
的过程:Fragment
的performXXX
()、onXXX
()方法;LifecycleRegistry
的handleLifecycleEvent
()方法;LifecycleObserver
的onXXX
()方法。
- Fragment中
performCreate()、performStart()、performResume()
会先调用自身的onXXX
()方法,然后再调用LifecycleRegistry
的handleLifecycleEvent()方法; - 而在
performPause()、performStop()、performDestroy()
中会先LifecycleRegistry
的handleLifecycleEvent
()方法,然后调用自身的onXXX
()方法。
比如上面的例子中,打印出来的结果也确实符合我们的分析,打印结果如下:
12-01 14:12:59.250 1398-1398/com.shymanzhu.architecture D/MainActivity: onCreate:
12-01 14:12:59.342 1398-1398/com.shymanzhu.architecture D/MainPresenter: onCreate:
12-01 14:12:59.345 1398-1398/com.shymanzhu.architecture D/MainActivity: onStart:
12-01 14:12:59.345 1398-1398/com.shymanzhu.architecture D/MainPresenter: onStart:
12-01 14:12:59.346 1398-1398/com.shymanzhu.architecture D/MainActivity: onResume:
12-01 14:12:59.346 1398-1398/com.shymanzhu.architecture D/MainPresenter: onResume:
12-01 14:12:59.601 1398-1412/com.shymanzhu.architecture D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
12-01 14:12:59.609 1398-1398/com.shymanzhu.architecture I/imx6.gralloc: open gpu gralloc module!
12-01 14:12:59.847 1398-1412/com.shymanzhu.architecture I/OpenGLRenderer: Initialized EGL, version 1.4
12-01 14:13:27.348 1398-1398/com.shymanzhu.architecture D/MainPresenter: onPause:
12-01 14:13:27.349 1398-1398/com.shymanzhu.architecture D/MainActivity: onPause:
12-01 14:13:28.265 1398-1398/com.shymanzhu.architecture D/MainPresenter: onStop:
12-01 14:13:28.266 1398-1398/com.shymanzhu.architecture D/MainActivity: onStop:
12-01 14:13:28.267 1398-1398/com.shymanzhu.architecture D/MainPresenter: onDestroy:
12-01 14:13:28.267 1398-1398/com.shymanzhu.architecture D/MainActivity: onDestroy:
其实这个Lifecycle组件是设计模式中观察者模式的例子
参考
1、Jetpack系列学习笔记整理一 之LifeCycles
2、Android Jetpack架构组件之 Lifecycles(使用篇)
3、Android Jetpack组件之Lifecycles库详解
4、Android Jetpack - Lifecycles
5、Android 架构组件(一)——Lifecycle
6、Android官方架构组件:Lifecycle详解&原理分析