1. 介绍
Lifecycle 是 Jetpack 中的一个生命周期感知组件,基于观察者模式来感知 Activity 和 Fragment 生命周期状态的变化。
在 Lifecycle 组件中,抽象类 Lifecycle 使用两个枚举来跟踪其关联组件的生命周期状态,分别是 Event 和 State:
/**
* Event 对应着 Activity 和 Fragment 的生命周期
*/
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY
}
/**
* State 用来记录当前关联的 Activity 或 Fragment 处于什么状态
*/
public enum State {
// 销毁状态
DESTROYED,
// 初始化状态
INITIALIZED,
// 创建但不可见状态
CREATED,
// 可见但未获取焦点状态
STARTED,
// 获取焦点状态
RESUMED
}
Lifecycle 组件的实现原理是:当 Activity 或 Fragment 生命周期变化时,被观察者通知观察者 Event 和 State 的变化,观察者根据这些变化来执行相应的操作。
因此,要了解 Lifecycle 内部原理,需要解答以下问题:
- 观察者和被观察者分别是谁?
- 观察者和被观察者如何关联?
- 被观察者如何感知
Activity和Fragment生命周期状态的变化? - 被观察者如何通知观察者生命周期状态的变化?
2. Lifecycle 中的观察者和被观察者
抽象观察者 LifecycleObserver
LifecycleObserver 是一个空接口,表示可以感知生命周期变化的观察者:
public interface LifecycleObserver {
// 空接口
}
具体观察者
具体的观察者需要实现 LifecycleEventObserver 接口,定义在生命周期变化时的具体行为:
public interface LifecycleEventObserver extends LifecycleObserver {
void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}
class MyLifecycleObserver implements LifecycleEventObserver {
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
switch (event) {
case ON_CREATE:
// 创建时的操作
break;
case ON_START:
// 可见时的操作
break;
case ON_RESUME:
// 获取焦点时的操作
break;
case ON_PAUSE:
// 失去焦点时的操作
break;
case ON_STOP:
// 不可见时的操作
break;
case ON_DESTROY:
// 销毁时的操作
break;
}
}
}
抽象被观察者 Lifecycle
Lifecycle 作为被观察者,定义了添加和移除观察者的方法:
public abstract class Lifecycle {
public abstract void addObserver(@NonNull LifecycleObserver observer);
public abstract void removeObserver(@NonNull LifecycleObserver observer);
}
具体被观察者 LifecycleRegistry
LifecycleRegistry 实现了 Lifecycle 接口,管理生命周期事件并通知观察者:
3. 添加和移除观察者
在 Activity 或 Fragment 中,我们可以通过 getLifecycle() 方法获取 Lifecycle 对象,并添加 LifecycleObserver:
示例代码
class MyLifecycleActivity : AppCompatActivity() {
private lateinit var myLifecycleObserver: MyLifecycleObserver
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
myLifecycleObserver = MyLifecycleObserver()
lifecycle.addObserver(myLifecycleObserver)
}
}
源码分析
上面代码中的 lifecycle 就是 LifecycleRegistry 对象。LifecycleRegistry 源码如下:
public class LifecycleRegistry extends Lifecycle {
private final SafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new SafeIterableMap<>();
private State mState;
/**
* 添加观察者
* @param observer 观察者对象
*/
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
// 检查是否在主线程
enforceMainThreadIfNeeded("addObserver");
// 初始化状态
State initialState = mState == State.DESTROYED ? State.DESTROYED : State.INITIALIZED;
// 创建 LifecycleObserver 的包装类 ObserverWithState
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
// 将 LifecycleObserver 添加到 map 中
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
if (previous == null && mState != State.INITIALIZED) {
// 调用 observer 的 onStateChanged 方法通知当前状态
statefulObserver.dispatchEvent(mLifecycleOwner, upEvent(mState));
}
}
@Override
public void removeObserver(@NonNull LifecycleObserver observer) {
enforceMainThreadIfNeeded("removeObserver");
// 将 LifecycleObserver 从 map 中移除
mObserverMap.remove(observer);
}
}
LifecycleRegistry 在添加观察者时,会检查当前的状态并立即通知新添加的观察者,使其与当前的生命周期状态同步。
4. Lifecycle 如何观察 Activity 的生命周期状态变化
Lifecycle 依赖于 LifecycleOwner 接口,Activity 和 Fragment 都实现了该接口。LifecycleOwner 提供了 getLifecycle 方法,用于获取 Lifecycle 实例:
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}
public class ComponentActivity extends AppCompatActivity implements LifecycleOwner {
// 创建被观察者对象 LifecycleRegistry
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
/**
* 实现 LifecycleOwner 的 getLifecycle 方法
* 返回创建的 LifecycleRegistry 对象
*/
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 将 mLifecycleRegistry 感知生命周期的任务交给 ReportFragment
ReportFragment.injectIfNeededIn(this);
}
}
在 ComponentActivity 中,实现了 LifecycleOwner 接口,并且在 getLifecycle 方法中返回创建的 LifecycleRegistry 对象。生命周期的感知任务被交给了 ReportFragment 处理。
ReportFragment 如何处理生命周期事件
public class ReportFragment extends Fragment {
// 通过 FragmentManager 添加 ReportFragment
public static void injectIfNeededIn(Activity activity) {
if (Build.VERSION.SDK_INT >= 29) {
ReportFragment.LifecycleCallbacks.registerIn(activity);
} else {
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 onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dispatch(Lifecycle.Event.ON_CREATE);
}
@Override
public void onStart() {
super.onStart();
dispatch(Lifecycle.Event.ON_START);
}
// ...省略其它生命周期方法
@Override
public void onDestroy() {
super.onDestroy();
dispatch(Lifecycle.Event.ON_DESTROY);
}
private void dispatch(@NonNull Lifecycle.Event event) {
if (Build.VERSION.SDK_INT < 29) {
// 仅在 API 29 之前通过 ReportFragment 分发事件
dispatch(getActivity(), event);
}
}
/**
* 将生命周期变化分发给 LifecycleRegistry
*/
static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
// 如果 Activity 实现了 LifecycleOwner 接口
if (activity instanceof LifecycleOwner) {
// 通过 LifecycleOwner 的 getLifecycle 获取 lifecycle 对象
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
// 调用 LifecycleRegistry 的 handleLifecycleEvent 方法
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
}
}
ReportFragment工作流程
dispatch(Activity activity, Lifecycle.Event event)方法:通过activity获取LifecycleRegistry对象,然后调用handleLifecycleEvent方法来将生命周期变化通知给LifecycleRegistry。- 调用
dispatch方法时机:在生命周期变化时会调用该方法。
当 API 级别大于或等于 29 时
dispatch(Activity activity, Lifecycle.Event event)方法依然会被调用,但不是在ReportFragment的生命周期变化中调用。registerActivityLifecycleCallbacks(new LifecycleCallbacks()):监听Activity生命周期变化,然后调用dispatch方法。
5. LifecycleRegistry 通知观察者生命周期状态变化
当 Activity 或 Fragment 生命周期状态变化时,LifecycleRegistry 调用 handleLifecycleEvent 方法,更新状态并通知所有观察者:
/**
* 设置当前状态并通知观察者
*
* @param event 接收到的事件
*/
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
enforceMainThreadIfNeeded("handleLifecycleEvent");
moveToState(event.getTargetState());
}
handleLifecycleEvent 方法中先调用了 event.getTargetState() 方法,根据 event 得到 State,然后调用 moveToState 方法设置新状态。getTargetState 方法源码如下:
/**
* 根据Event获取State
*/
@NonNull
public Lifecycle.State getTargetState() {
switch (this) {
case ON_CREATE:
case ON_STOP:
return Lifecycle.State.CREATED;
case ON_START:
case ON_PAUSE:
return Lifecycle.State.STARTED;
case ON_RESUME:
return Lifecycle.State.RESUMED;
case ON_DESTROY:
return Lifecycle.State.DESTROYED;
case ON_ANY:
break;
}
throw new IllegalArgumentException(this + " has no target state");
}
getTargetState 方法比较好理解,比如当前执行了 ON_CREATE 事件或者 ON_STOP 事件,那么状态就会处于 CREATED。继续看 moveToState 方法,如下:
private void moveToState(Lifecycle.State next) {
//如果状态没有变化,直接return
if (mState == next) {
return;
}
//设置新状态
mState = next;
//mAddingObserverCounter:正在添加观察者数量
if (mHandlingEvent || mAddingObserverCounter != 0) {
//mNewEventOccurred:是否有新事件产生
mNewEventOccurred = true;
// we will figure out what to do on upper level.
return;
}
//mHandlingEvent: 是否在处理事件
mHandlingEvent = true;
sync();
mHandlingEvent = false;
}
moveToState 方法设置新状态,然后调用 sync 方法。在 Lifecycle 中,通过三个变量:mHandlingEvent、mNewEventOccurred、mAddingObserverCounter 的配合,来解决事件嵌套引起的 sync() 多次执行。初次了解 Lifecycle 原理时,可以先忽略这三个变量,后续了解 Lifecycle 大概流程后再来思考这个问题。下面继续看 sync 方法,源码如下:
// happens only on the top of stack (never in reentrance),
// so it doesn't have to take in account parents
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.");
}
//isSynced():状态是否是同步的
//map中保存的首尾节点的观察者状态以及mState记录的当前状态相同,说明已同步
while (!isSynced()) {
mNewEventOccurred = false;
//比较mState和尾节点状态
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
//状态向后
backwardPass(lifecycleOwner);
}
Map.Entry<LifecycleObserver, LifecycleRegistry.ObserverWithState> newest = mObserverMap.newest();
//比较mState和首节点状态
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
//状态向前
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
在 sync 方法中,会根据当前状态和 mObserverMap 中的 eldest 和 newest 的状态做对比,判断当前状态是向前还是向后。比如由 STARTED 到 RESUMED 是状态向前,反过来就是状态向后。forwardPass 和 backwardPass 方法的代码类似,这里以 forwardPass 为例:
private void forwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
mObserverMap.iteratorWithAdditions();
while (ascendingIterator.hasNext() && !mNewEventOccurred) {
Map.Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
//取出ObserverWithState对象
ObserverWithState observer = entry.getValue();
//比较当前状态mState和observer记录的状态
while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
pushParentState(observer.mState);
//upFrom:状态向前。比如observer.mState是STARTED,则变为RESUME
final Event event = upFrom(observer.mState);
if (event == null) {
throw new IllegalStateException("no event up from " + observer.mState);
}
//调用ObserverWithState的dispatchEvent方法,通知观察者
observer.dispatchEvent(lifecycleOwner, event);
popParentState();
}
}
}
在 forwardPass 方法中,会同步状态,然后调用 ObserverWithState 的 dispatchEvent 方法,通知观察者。
ObserverWithState 是观察者 LifecycleObserver 的包装类,使其带有生命周期状态。
并提供了 dispatchEvent 方法,在 dispatchEvent 方法中通知观察者生命周期的变化。
static class ObserverWithState {
//生命周期状态--Lifecycle中定义的enum State{}
State mState;
//观察者对象
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
//这里的observer对象可能是LifecycleEventObserver类型,
//也可能是FullLifecycleObserver类型,
//lifecycleEventObserver方法将对象统一转化为LifecycleEventObserver类型。
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
//初始化状态
mState = initialState;
}
//分发事件
void dispatchEvent(LifecycleOwner owner, Event event) {
//根据Event得出当前最新的State状态
State newState = event.getTargetState();
mState = min(mState, newState);
//触发观察者对象的onStateChanged()方法
mLifecycleObserver.onStateChanged(owner, event);
//更新状态
mState = newState;
}
}
总结
通过使用 Lifecycle 组件,开发者可以将生命周期相关的逻辑与业务逻辑分离,使代码更加模块化和易于维护。具体实现中,通过添加 LifecycleObserver 观察者,可以在 Activity 和 Fragment 的生命周期变化时接收通知并执行相应操作。LifecycleRegistry 在 Activity 或 Fragment 的生命周期方法中调用 handleLifecycleEvent,从而触发观察者的 onStateChanged 方法。