大家在看这篇文章的时候最好自己也点开源码跟着一步一步看一看,这样印象深刻
先看一句Lifecycle最常用的代码:
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
}
});
被观察者Activity或者Fragment设置了一个观察者LifecycleEventObserver来观察他们的生命周期,作用就是在被观察者Activity或者Fragment的生命周期变化时能回调onStateChanged方法
那么问题来了:
1.Lifecycle是什么,它是如何和Activity或者Fragment结合的
2.Lifecycle是怎么做到能监听LifecycleOwner(Activity或Fragment)的生命周期的
3.Lifecycle具体是以何种方式监听
4.在监听到生命周期后如何通知的观察者LifecycleObserver
回答:
1.Lifecycle是什么,它是如何和Activity或者Fragment结合的
1. Lifecycle是一个管理生命周期的工具类,Lifecycle是一个抽象类,它通过Event枚举类型维护了生命周期分别对应的状态,通过State维护了执行了某一个生命周期函数后和在执行下一个生命周期函数前被观察者(Activity或Fragment)处于什么状态,好多人不李姐State是啥和干啥用的来张图理解李姐:
这个State就是用来具体化描述两个生命周期之间的状态,作用在回答第三个问题会给出。
上面说到Lifecycle维护了两个枚举类型一个Event是对应生命周期函数,一个State对应生命周期之间处于什么状态,Lifecycle的实现类LifecycleRegistry才是重点,就是通过这个类实现的监听到生命周期变化后通知的观察者,具体怎么通知的在第4小问回答。先看一下Lifecycle怎么和Activity结合的或者说凭什么在Activity中调用getLifecycle就能得到Lifecycle:在ComponentActivity中
LifecycleRegistry是直接在ComponentActivity中new出来,这样Activity就持有了LifecycleRegistry的引用
LifecycleOwner接口作用就是获取Lifecycle ,这里说一下接口的本质:接口的本质就是定义了一项能力,实现了这个接口就相当于这个类有了这项能力
在ComponentActivity实现了LifecycleOwner这个接口,所以它有了通过这个接口提供LifeCycle的能力
2.Lifecycle是怎么做到能监听LifecycleOwner(Activity或Fragment)的生命周期的
2.Lifecycle是通过在Activity中绑定了一个空的fragment来实现监听Activity的生命周期的,因为如果在Activity中添加一个fragment 那在fragment的生命周期执行的时候 就能知道宿主对应的生命周期执行了
在ComponentActivity的onCreate方法中添加一个名字为ReportFragment空Fragment
具体添加ReportFragment的具体代码
因为ReportFragment添加在Activity上之后Activity的生命周期执行的时候会对应的执行ReportFragment的生命周期方法,所以在添加的ReportFragment的生命周期方法中就能监听Activity的生命周期了
3.Lifecycle具体是以何种方式监听,和回答第一个回答留的坑State的作用
3. 上面提到通过在Activity中添加空白的ReportFragment,并且在空白的ReportFragment的生命周期中实现监听Actiivty的生命周期变化。通过图片中的代码可以知道在ReportFragment中生命周期方法中通过调用dispatch(Lifecycle.Event)方法分发的生命周期状态:
这个Lifecycle.Event参数就是生命周期方法对应的枚举类型
下面重点分析Lifecycle的实现类LifecycleRegistry的handleLifecycleEvent方法:
先看static State getStateAfter(Event event)方法:
已知这个event参数是生命周期对应的枚举类型,这个方法的作用就是在被观察者(Activity或Fragment)执行了某一个Event生命周期方法后对应的是State的哪一个状态。
再分析private void moveToState(State next)
这个State next参数就是被观察者Activity或Fragment刚刚执行了哪个生命周期,要明确我们的目的就是在监听到被观察者生命周期变化后具体是怎么运作把被观察者的生命周期的变化,先同步到Lifecycle之后再,同步到观察者的
如果发现State的值不同,意味者被观察者一定执行了某个生命周期方法,这时候就需要把执行后的生命周期方法和处于的State状态同步到Lifecycle中,并且通知观察者,它观察的宿主生命周期变化了。如何通知的观察者
重点就在sync()方法:
重点标记的这两段代码,有一个疑问mObserverMap是用来存储什么的
可以看出mObserverMap是用来存储ObserverWithState的,而这个ObserverWithState就是观察者LifecycleEventObserver的包装类
我们重点分析的sync()方法中:
我们只分析一个分支backwardPass
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0)
这句代码的意思就是mState被观察者处于的状态,是不是比观察者保存的状态小,如果是,那观察者需要执行的生命周期就能推算出来。如何推算,出个应用题(被观察者和观察者开始State状态相等,后来被观察者执行了一个生命周期方法后比观察者的状态小了,已知现在的被观察者的状态,求被观察者执行了什么生命周期方法)
State大小:DESTROYED < INITIALIZED < CREATED < STARTED < RESUMED
例如:已知状态大小的顺序,现在观察者和被观察者的状态都是RESUMED,被观察执行了了一个方法后状态变成了STARTED,问执行了哪个方法?
毫无疑问是onPase方法,这里也就回答了上面提出的State的作用是什么就是状态机的状态
这个应用题的逻辑的实现就是 这个方法:
通过状态机我们就知道被观察者是因为执行了哪个生命周期导致了State状态发生了这样的变化(变大或变小)。
4.在监听到生命周期后如何通知的观察者LifecycleObserver
虽然代码看上去很合理,能通知到了,但是怎么联系起来的呢?
又要回到这里:
这次相信大家的解读会更详细些:
在获取这个Activity中的Lifecycle的实现类LifecycleRegist后,执行了LifecycleRegist的addObserver方法并把我们的观察者当作参数传了进去:
然后把我们的观察者打包到包装类ObserverWithState中(包装类就是处理观察者的工具类),然后再把包装类存到mObserverMap中
观察者的包装类:
可以看到只要执行了diapatchEvent方法就能,让观察者的onStateChange方法得到执行也就能通知我们的观察者了
而上面看到我们的Lifecycle是如何通知观察着的呢?
可以看到就是通过遍历我们的mObserverMap来得到观察者包装类,调用的dispatchEvent方法,然后通知到的
那再思考一下,这两个mObserverMap是一个实例吗,如果是一个实例那就能保证我们存取的是同一个观察者,就肯定能通知到被观察者的生命周期变化了
可以看出它是Lifecycle的实现类LifecycleRegistry的一个成员方法,现在只要保证LifecycleRegistry是同一个实例就行了
好了,Lifecycle管理生命周期的原理主线流程分析完毕,一切归于平静了。
总结一下:
Activity通过添加空fragment的方法实现监听生命周期变化,在被观察者生命周期变化时计算出执行完生命周期后的State状态,然后通过状态机计算出,应该执行哪个生命周期,最后通知观察者
补充: 如果从其他生命周期开始注册会怎样,例如从onResume或者onPause方法中注册,是直接从注册这个生命周期之后开始,还是需要顾及之前的生命周期?
答案是:需要顾及之前的生命周期,例如在onResume方法注册的话是会执行onCreate的回调和onStart的回调的看示例代码:
@Override
protected void onResume() {
super.onResume();
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
System.out.println("生命周期:" + event);
}
});
}
执行结果:
在注册时初始状态都是INITIALIZED,它会和当前的状态进行比较,然后一步一步的上升到当前状态。
不同的生命周期有一些差别:onPause,onStop,onDestroy这些方法,都是先LifeCycle监听到执行onPause,onStop,onDestroy,再执行onPause,onStop,onDestroy方法进行注册的,而onCreate,onResume,onStart是先执行方法注册,再LifeCycle监听到执行onCreate,onResume,onStart,这是为什么?
下一篇:LiveData原理,源码分析,通俗易懂