前言
之前虽然对Lifecycle的源码有一个大概的理解,但是感觉还是模棱两可,于是直接全面领略了一遍源码的风采。
今天就由浅入深直接带大家来了解一下它的原理。如果不想看长篇源码,可以直接跳**「总结」**
首先来看看它的使用
使用
首先我们先创建一个类实现DefaultLifecycleObserver
,这样我们的观察者就定义好了
class SampleLifecycle : DefaultLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {
super.onCreate(owner)
Log.e(TAG, "onCreate: ")
}
override fun onStart(owner: LifecycleOwner) {
super.onStart(owner)
Log.e(TAG, "onStart: ")
}
override fun onResume(owner: LifecycleOwner) {
super.onResume(owner)
Log.e(TAG, "onResume: ")
}
override fun onPause(owner: LifecycleOwner) {
super.onPause(owner)
Log.e(TAG, "onPause: ")
}
override fun onStop(owner: LifecycleOwner) {
super.onStop(owner)
Log.e(TAG, "onStop: ")
}
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
Log.e(TAG, "onDestroy: ")
}
companion object {
private const val TAG = "SampleLifecycle"
}
}
在Activity 或者Fragment 添加监听
lifecycle.addObserver(SampleLifecycle())
这样当我们UI状态进行变化的时候就会接收到状态监听了。在使用上非常简单方便
接下来,就带领大家领略一下它的实现原理。
原理
添加观察者
首先我们从添加观察者说起,在Activity中,为什么可以获取到Lifecycle
?
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
跳转源码,可以看到在父类ComponentActivity
中,实现 LifecycleOwner
接口, getLifecycle
返回了 mLifecycleRegistry
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
ContextAware,
LifecycleOwner,
............
{
............
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
............
}
在 ComponentActivity 创建的时候,同时创建了 LifecycleRegistry ,LifecycleRegistry 是Lifecycle 子类。
看到这里就可以理解为什么可以在Activity 里 添加观察者了。
接下来我们看下,添加观察者。
LifecycleRegistry类
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
enforceMainThreadIfNeeded("addObserver");
//初始状态
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
//通过ObserverWithState将观察者和状态进行包装
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
//将包装类放到 FastSafeIterableMap<LifecycleObserver, ObserverWithState> 中 。
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
............
//将状态进行对齐
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
final Event event = Event.upFrom(statefulObserver.mState);
if (event == null) {
throw new IllegalStateException("no event up from " + statefulObserver.mState);
}
statefulObserver.dispatchEvent(lifecycleOwner, event);
popParentState();
targetState = calculateTargetState(observer);
}
if (!isReentrance) {
//同步状态
sync();
}
mAddingObserverCounter--;
}
使用 ObserverWithState
类 将观察者对象和状态进行包装,然后存储在 FastSafeIterableMap
中,这里先对ObserverWithState
这个类有点印象, 在下文事件分发的时候,会再详细讲解。
FastSafeIterableMap 具有以下特性:
- 支持键值对存储,用链表实现,模拟成Map的接口
- 支持在遍历的过程中删除任意元素,不会触发ConcurrentModifiedException
- 非线程安全
注释中提到的将状态进行对齐,是在添加观察者的时候,可能是在任何状态的时候进行添加的,lifecycle需要将这个状态进行对齐。
例如我们在onResume的回调中添加了观察者,此时我们的观察者就收到依次收到 onCreate
, onStart
,onResume
的回调。
监听生命周期
我们的观察者是怎样收到Activity 的生命周期的监听的呢?
这里我们看下父类ComponentActivity
的onCreate方法中,有一个这样的操作
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
............
ReportFragment.injectIfNeededIn(this);
if (mContentLayoutId != 0) {
setContentView(mContentLayoutId);
}
}
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();
// Hopefully, we are the first to make a transaction.
manager.executePendingTransactions();
}
}
在 ComponentActivity
创建的时候,同时创建了ReportFragment
,这个Fragment
的作用就是用来分发生命周期状态的。
在ReportFragment
的每个生命周期的回调中,都对应的调用了 dispatch
方法 ,来进行状态分发。
最后 dispatch
的方法中,又调用了 LifecycleRegistry
的handleLifecycleEvent
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
enforceMainThreadIfNeeded("handleLifecycleEvent");
moveToState(event.getTargetState());
}
我们当前的状态是通过 event.getTargetState()
来获取的
public State getTargetState() {
switch (this) {
case ON_CREATE:
case ON_STOP:
return State.CREATED;
case ON_START:
case ON_PAUSE:
return State.STARTED;
case ON_RESUME:
return State.RESUMED;
case ON_DESTROY:
return State.DESTROYED;
case ON_ANY:
break;
}
throw new IllegalArgumentException(this + " has no target state");
}
这里是维护了一个状态机,可能有的同学不明白为什么ON_CREATE 和 ON_STOP 状态 都是属于 State.CREATED 状态,接下来用一张图来解释一下
State 一共维护了 DESTROYED
, INITIALIZED
, CREATED
,STARTED
, RESUMED
五种状态
上图简要说明了一下 各个生命周期回调时,分别对应的状态,整个状态趋势 是分为 正在可见 和正在不可见。
通过状态机获取当前的状态之后,会将当前状态进行记录,然后会 执行 sync()
方法进行同步操作。
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
......
//当 mObserverMap 中存储的最新的状态(刚插入的) 与 最老的状态(最先插入的) 一致,并且当前状态等于最新的状态,停止同步。
while (!isSynced()) {
mNewEventOccurred = false;
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
在这里会通过当前状态和存储的状态进行比较操作,判断当然流程 是 向正在可见发展 还是 正在向不可见发展,
例如当前执行的状态是START
,与上个状态相比,如果上个状态是CREATE
,相比结果就是>0 ,说明是正在可见;如果上个状态是RESUME
,相比结果<0 ,说明是正在不可见。
backwardPass
和 forwardPass
主要有两点不同
1.在对mObserverMap
存储的状态进行遍历时,backwardPass
是以 栈的形式遍历,forwardPass
是以队列的形式遍历。
2.对状态还原的时候,backwardPass
是不可见方向还原,也就是上图的粉色箭头方向,forwardPass
是以可见方向还原,也就是上图的 青绿色箭头方向。
最后是通过ObserverWithState
的 dispatchEvent
方法 进行了分发。
最后是怎样通知到我们对应的观察者对象的呢?
ObserverWithState
在上文有提到,是对观察者对象和状态进行了一个包装,在这里我们来详细看一下。
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = event.getTargetState();
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
我们先看包装的时候的操作,是执行了一个 Lifecycling.lifecycleEventObserver(observer)
操作。
static LifecycleEventObserver lifecycleEventObserver(Object object) {
boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;
boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;
if (isLifecycleEventObserver && isFullLifecycleObserver) {
return new FullLifecycleObserverAdapter((FullLifecycleObserver) object,
(LifecycleEventObserver) object);
}
if (isFullLifecycleObserver) {
return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, null);
}
}
是返回一个对应类型 的实例化对象 ,我们自定义的观察者,实现的是DefaultLifecycleObserver
接口,DefaultLifecycleObserver
接口又继承了FullLifecycleObserver
,所以这里会新建一个 FullLifecycleObserverAdapter
对象,并返回,
再看 ObserverWithState
的 dispatchEvent
操作,调用了 onStateChanged
方法,然后就会调用到 FullLifecycleObserverAdapter
的 onStateChanged
里面
在这里面 就是进行接口回调,然后我们的观察者就可以接收到生命周期的回调了。
分析到这里,我们就可以将整个 添加观察者,对应生命周期时间 分发 的过程全部联系起来了。
总结
在这里我们总结一下:
首先自定义观察者,实现了FullLifecycleObserver
接口,Activity
的父类ComponentActivity
实现了 LifecycleOwner
,所以可以添加观察者,并且自己的onCreate
方法中,创建并添加了一个ReportFragment
,用来感应自身的生命周期的回调, 并进行对应分发。
在分发过程中,Lifecycle
通过内部维护的状态机 将生命周期事件转化为State
状态,并进行存储,在 分发过程中,通过状态比较来判断 当前过程是正在可见还是正在不可见,不同过程采用不同策略。最后通过调用 LifecycleEventObserver
的 onStateChanged
方法 来进行回调。
写在最后
整体来说,整个框架原理并不是很难理解,主要是状态机那部分,需要多思考一下, 最好借助图像工具 具体的展示出来。
今天的分享就到这里,希望这篇文章在你学习Lifecycle的路上能够有所帮助。