0%

lifecycle

监听 Activity 和 Fragment 的生命周期。

我们使用 LifeCycle 必须要使用 AndroidX ,LifecycleOwner 是个 接口,官方称为宿主

1
2
3
4
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}

而 Lifecycle 本身是个抽象类,因此不能直接使用:

1
2
3
4
5
6
7
8
9
10
11
public abstract class Lifecycle {
//省略很多代码

@MainThread
public abstract void addObserver(@NonNull LifecycleObserver observer);


@MainThread
public abstract void removeObserver
(@NonNull LifecycleObserver observer);
}

因为不能直接使用 LifeCycle ,所以在必须要有实现类来实现,我们可以看 ComponentActivity 类,因为它实现了 LifecycleOwner 接口,必须要返回一个 Lifecycle 对象,从这里看是 LifecycleRegistry 对象:

1
2
3
4
5
6
7
8
9
10
11
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
ContextAware,
LifecycleOwner,...... {

// 省略其他无关代码
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
}

Lifecycle 使用一个没有 UI 的 名叫 ReportFragment 的 Fragment 来监听宿主的生命周期变化,因为 Fragment 的生命周期会随着宿主变化而变化。通过在 Activity/Fragment 里面 getLifecycle().addObserver(LifecycleObserver) 即可实现生命周期的监听。

我们的 LifecycleObserver 在 add 进去之后,就会被当成成员变量保存,然后获取它的class 对象,获取 class 对象肯定就是要去通过反射。一般源码中,需要反射的地方会有 map 来缓存 Class 对象,比如 setContentView。

哪怕你是在 onResume 中 去执行 getLifecycle().addObserver(LifecycleObserver) ,那么还是会给你从 create 、start 、resume 一样不落地执行,所以,在同步状态的时候,会有个 while 循环。通过状态来激活事件,这样由于宿主的状态是 onResume 了,但是你的 Observer 才注册进来,中间相差了 create 、start 、resume 这三个状态,就 while 循环一步步改状态,调事件。如果是在 onStop 中去做 addObserver ,则只会有 create 、destroy 状态。

在 LifeCycle 里面,并不是说 Activity/Fragment 的 onStart ,然后就会通过接口调用观察者的 onStart ,它里面有个状态转换,被转成 5 种状态:INITIALIZED(刚添加进来)、CREATED、STARTED、RESUMED、DESTROYED ,之后,回调给观察者的方法是根据顺序(宿主Activity/Fragment 的状态在观察者前面,比如宿主是 STATED 了,观察者还在 CREATED)还是倒序来推断的,以下是转换代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
   //androidx.lifecycle.Lifecycle.java
@NonNull
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");
}
}

顺序和倒序的事件驱动过程如下图所示:

Lifecycle顺序倒序事件及状态变化

在宿主(Activity/Fragment)和观察者(Observer)同步状态的时候,就会发生顺序和倒序的路径判断,最终回调事件给观察者,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//androidx.lifecycle.LifecycleRegistry
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
+ "garbage collected. It is too late to change lifecycle state.");
}
//有个 while 循环是因为可能你会在 onResume 里面添加观察者,这样要把
//状态从前面CREATED 一直同步到 RESUME
while (!isSynced()) {
mNewEventOccurred = false;
// no need to check eldest for nullability, because isSynced does it for us.
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;
}

里面的 while 循环是因为可能你会在 onResume 里面添加观察者,这样要把状态从前面CREATED 一直同步到 RESUME ,然后 里面的 backwardPass 和 forwardPass 分别代表倒序和顺序。

那么,为什么要这么设计呢?这是因为 Lifecycle 不只是给我们在Activity 种监听生命周期这么简单,还会给很多诸如 LiveData 这类的框架使用,所以它还会衍生出其他内容,比如 LiveData 在使用 LifeCycle 就使用了 LifecycleBoundObserver ,它里面实现了一个 boolean 类型的判断宿主是否在活动状态:

1
2
3
4
5
//LiveData 内部类LifecycleBoundObserver
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}

只有 STARTED 和 RESUME 才符合条件。

因为前面存储了各个 add 进去的 Observer ,并获取了他们的 Class 对象,所以,在顺序或者倒序确定哪个生命周期之后,就会调用 Class.invoke 来调用对应的生命周期回调方法。

谢谢你的鼓励