Lifecycle原理剖析
1. Lifecycle是什么?
Lifecycle 是具备宿主生命周期感知能力的组件。它能持有组件(如 Activity 或 Fragment)生命周期状态的信息,并且允许其他观察者监听宿主的状态。它也是 Jetpack 组件库的的核心基础,包括我们就后面会讲到的 LiveData , ViewModel 组件等也都是基于它来实现的。
2. 学习内容
本文章我们主要对Jetpack中的核心组件Lifecycle进行讲解,通过本文章我们将会学到:
- Fragment和Activity 是如何实现 Lifecycle 能力的?
- 如何利用 Lifecycle 组件观察宿主生命周期的变化?
- Lifecycle 又是如何根据宿主状态分发事件给观察者的?
3. Lifecycle的主要组成
先简单了解一下整个Lifecycle的核心组成
-
LifecycleOwner是一个接口,继承该接口的目的是为了声明它是一个能够提供生命周期事件的宿主。同时必须复写getLifecycle()方法提供一个Lifecycle对象。
-
Lifecycle是一个抽象类,里面定义了两个枚举:State宿主的状态,Event 事件的类型,然后定义了添加删除Observer函数,还有获取现在状态的函数,可以看出来Lifecycle的作用就是保存宿主状态,并且负责分发。
-
LifecycleRegistry是 Lifecycle 的唯一实现类,主要用来负责注册 Observer,以及分发宿主状态事件给它们。
-
LifecycleObserver是宿主状态变化后通知监听者的回调
4. 怎么使用Lifecycle监听宿主状态?
4.1 创建监听对象
创建LifecycleObserver 有三种实现方法,下面我们来介绍一下:
4.1.1 FullLifecyclerObserver
FullLifecyclerObserver 拥有宿主所有生命周期事件:
//1.源码,目前这个类权限不可见,即便如此,我们也要了解它
interface FullLifecycleObserver extends LifecycleObserver {
void onCreate(LifecycleOwner owner);
void onStart(LifecycleOwner owner);
void onResume(LifecycleOwner owner);
void onPause(LifecycleOwner owner);
void onStop(LifecycleOwner owner);
void onDestroy(LifecycleOwner owner);
}
//2.用法,需要监听那个事件,复写那个方法即可
class LocationObserver extends FullLifecycleObserver{
void onStart(LifecycleOwner owner){}
void onStop(LifecycleOwner owner){}
}
4.1.2 LifecycleEventObserver
LifecycleEventObserver宿主生命周期事件封装成 Lifecycle.Event
//1.源码
public interface LifecycleEventObserver extends LifecycleObserver {
void onStateChanged(LifecycleOwner source, Lifecycle.Event event);
}
//2.用法
class LocationObserver extends LifecycleEventObserver{
@override
void onStateChanged(LifecycleOwner source, Lifecycle.Event event){
//需要自行判断life-event是onstart, 还是onstop
}
}
4.1.3 LifecycleObserver + 注解
//1. 自定义的LifecycleObserver观察者,在对应方法上用注解声明想要观 察的宿主的生命周期事件即可
class LocationObserver extends LifecycleObserver{
//宿主执行了onstart时,会分发该事件
@OnLifecycleEvent(Lifecycle.Event.ON_START)
void onStart(@NotNull LifecycleOwner owner){
//开启定位
}
//宿主执行了onstop时 会分发该事件
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void onStop(@NotNull LifecycleOwner owner){
//停止定位
}
}
//2. 注册观察者,观察宿主生命周期状态变化
class MyFragment extends Fragment{
public void onCreate(Bundle bundle){
LocationObserver observer =new LocationObserver()
getLifecycle().addObserver(observer);
}
}
以上的方式我常用的是第二种,虽然用注解很爽,但是如果没有添加 lifecycle-compiler 这个注解处理器的话,运行时会使用反射的形式回调到对应的方法上。
4.2 Lifecycle是如何分发宿主状态的?
4.2.1 宿主状态介绍
public abstract class Lifecycle {
public enum State {
//已销毁
DESTROYED,
//宿主已经构造完
INITIALIZED,
//宿主已完成创建
CREATED,
//宿主已经可见
STARTED,
//宿主已经聚焦
RESUMED;
}
}
4.2.2 事件介绍
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY;
事件基本就是我们熟悉的事件啦,在某个状态至某个状态变更时候,会触发某个事件,我们看下图:
了解完Lifecycle关键组成与状态和事件后,我们看看Fragment和Activity是怎么实现Lifecycle的吧~
4.3 Fragment/Activity是怎么实现Lifecycle的?
4.3.1 Fragment如何实现Lifecycle
Fragment 实现 LifecycleOwner 接口,并且创建了LifecycleRegistry实例,然后在各个生命周期方法内利用LifecycleRegistry分发相应的事件给每个观察者,以实现生命周期观察的能力:
//1.Fragment首先实现了LifecycleOwner接口
public class Fragment implements LifecycleOwner {
//3.创建LifecycleRegistry,用于分发与保存状态
LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
//2.重写了LifecycleOwner接口中的getLifecycle方法,返回了LifecycleRegistry对象
@Override
public Lifecycle getLifecycle() {
//复写自LifecycleOwner,所以必须new LifecycleRegistry对象返回
return mLifecycleRegistry;
}
//4.在回调中通知mLifecycleRegistry通过handleLifecycleEvent函数进行事件分发
void performCreate(){
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
void performStart(){
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
}
.....
void performResume(){
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
}
}
4.3.2 Activity如何实现Lifecycle
Activity 实现 Lifecycle 需要借助于 ReportFragment 往 Activity 上添加一个 fragment 用以报告生命周期的变化,目的是为了兼顾不是继承自 AppCompactActivity 的场景。
//1.实现LifecycleOwner接口
public class ComponentActivity extends Activity implements LifecycleOwner{
//2.声明LifecycleRegistry对象
private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
//3.重写LifecycleOwner接口中的方法,返回LifecycleRegistry对象
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
protected void onCreate(Bundle bundle) {
super.onCreate(savedInstanceState);
//4.往Activity上添加一个ReportFragment,用以报告生命周期的变化
//目的是为了兼顾不是继承自AppCompactActivity的场景.
ReportFragment.injectIfNeededIn(this);
}
接着我们看看ReportFragment的具体实现~
这里的实现其实跟 Fragment 中的源码是一样的,在各个生命周期方法内利用 LifecycleRegistry 派发相应的 Lifecycle.Event 事件给每个观察者:
public class ReportFragment extends Fragment{
public static void injectIfNeededIn(Activity activity) {
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
manager.executePendingTransactions();
}
}
@Override
public void onStart() {
super.onStart();
dispatch(Lifecycle.Event.ON_START);
}
@Override
public void onResume() {
super.onResume();
dispatch(Lifecycle.Event.ON_RESUME);
}
@Override
public void onPause() {
super.onPause();
dispatch(Lifecycle.Event.ON_PAUSE);
}
@Override
public void onDestroy() {
super.onDestroy();
dispatch(Lifecycle.Event.ON_DESTROY);
}
private void dispatch(Lifecycle.Event event) {
Lifecycle lifecycle = activity.getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
所以Activity为了兼容性,巧妙的装载了一个Fragment在页面上,通过Fragment代理生命周期的形式发送事件。
4.3.3 那么在添加监听时,Lifecycle做了啥?
基于 Lifecycle 的特性我们在任意生命周期方法内注册观察者都能接收到完成的生命周期事件,比如在onResume 中注册一个观察者,它会依次收到:
LifecycleEvent.onCreate -> LifecycleEvent.onStart -> LifecycleEvent.onResume
接下来我们就看看源码做了啥?
public class LifecycleRegistry extends Lifecycle {
//1.通过addObserver函数对宿主进行监听
public void addObserver(@NonNull LifecycleObserver observer) {
//2.对比宿主状态,如果不是DESTROYED,则需从INITIALIZED事件开始同步
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
//3.我们有三种声明监听的方式,所以Lifecycle统一用ObserverWithState进行包装,让ObserverWithState自己根据监听的类型再分发事件
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
//4.尝试添加到Map中,如果已经添加过则返回已经添加了额对象
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
//5.不重复添加监听
if (previous != null) {
return;
}
//6.判断宿主是否存在
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}
//7.为了与宿主的状态同步,所以先获得现在监听器中的状态,通过对比同步宿主与监听器的状态
State targetState = calculateTargetState(observer);
//8.循环会直到监听器中的状态与宿主状态同步位置,期间会根据顺序不断通知监听器发送事件
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
//9.为当前监听器的状态上升一级,并且返回相应时间,比如从CREATED上升到STARTED,则生成ON_START事件
final Event event = Event.upFrom(statefulObserver.mState);
//10.分发事情至监听中
statefulObserver.dispatchEvent(lifecycleOwner, event);
//11.计算当前状态,再次循环至第八步,直到与宿主状态同步
targetState = calculateTargetState(observer);
}
}
}
通过上面源码,我们可以了解了,为啥我们注册一个监听器时,会依次收到事件回调。
4.3.3.1 了解一下ObserverWithState
ObserverWithState这个命名其实已经很直白了,告诉我们这个就是监听器与状态的包装类,而持有观察者的状态,是方便与宿主状态做比对同步。
我们看一下源码:
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
//把传入的LifecycleObserver适配成LifecycleEventObserver,目的是为了统一事件的分发形式
//因为我们前面提到观察者有三种类型,每种类型接收事件的形式并不一样,如果在分发的时候不统一事件分发的形式,将会变得很麻烦
//至于是如何适配转换的,由于不是本文重点,所以不再详细展开
//但核心思想这里说明一下,同学们自行看下就能明白
//它会判断传入的observer是前面提到的那一种类型,进而转换成对应的适配器类,适配器类会对onStateChanged方法进行适配,并以相应的方式(反射、中转、)把事件转发到我们的observer上
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
//再一次根据需要分发的事件类型反推出该观察者的状态,这样的好处是事件 & 状态 一一对应,不会出现跳跃。但阅读上可能会稍微有点绕
State newState = getStateAfter(event);
mState = min(mState, newState);
//把事件分发给被包装的对象,完成本次流程。
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
4.3.4 当宿主状态变化时,怎么分发事件?
首先我们以Fragment的实现为例看看:
void performCreate(){
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
确认是通过handleLifecycleEvent函数分发事件的,那么这个时候就看看LifecycleRegistry的实现吧:
//1.推断状态并准备分发事件
public void handleLifecycleEvent(@NonNull Lifecycle.Event event){
//宿主的每个生命周期的变化都会分发一个对应的Lifecycle.Event,走到这里
//此时会根据需要分发的事件反推出 宿主当前的状态
State next = getStateAfter(event);
moveToState(next);
}
//2.保存状态,准备给分发事件
private void moveToState(State next) {
if (mState == next) {
return;
}
mState = next;
//确认状态后,开始同步给已注册的监听器
sync();
}
//3.分发事件给每一个监听器
private void sync() {
//isSynced函数就是判断第一个监听者的状态是否与宿主一直再判断对比第一个监听者和最后一个监听者是否一致,如果不一直则说明监听者列表没有同步完毕
while (!isSynced()) {
//如果宿主当前状态 小于 mObserverMap集合中最先添加的那个观察者的状态
//则说明宿主可能发生了状态回退,比如当前是RESUMED状态,执行了onPause则回退到STARTED状态
//此时调用backwardPass把集合中的每个一观察者分发一个on_pause事件,并同步它的状态。
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
//如果宿主当前状态 大于 mObserverMap集合中最先添加的那个观察者的状态
//则说明宿主可能发生了状态前进,比如当前是STARTED状态,执行了onResume则前进到RESUMED状态
//此时调用forwardPass把集合中的每个一观察者分发一个on_resume事件,并同步它的状态。
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
}
通过上面的讲解了,我们了解到了Lifecycle的组成,Fragment和Activity是怎么实现Lifecycle的,注册监听器过程分别做了什么,分发事件的时候是怎么分发到每一个监听器,相信大家都了解了~