Lifecycle 原理与实践

1,440 阅读8分钟

Jetpack框架已经出现了很久,但一直没有系统的学习和总结,趁着现在有空学习一波。可以一起学习和交流

其中Lifecycle作为其中的最基础的组件,其他的组件和项目中也经常的使用,因此觉得Lifecycle是基础重中之重,故此将Lifecycle放在第一篇,作为开篇之作。

简单理解LifeCycle 是一个可以感知宿主生命周期变化的组件。包括 Activity/Fragment、Service 和 Application。LifeCycle 会持有宿主的生命周期状态的信息,当宿主生命周期发生变化时,会通知监听宿主的观察者。

本文目标:

  • Lifecycle出现的背景和要达到什么目的
  • Lifecycle的应用场景
  • Lifecycle的组成部分和关键点
  • Lifecycle的底层原理和关键实现

Lifecycle出现的背景

先看下不使用Lifecycle之前的做法:

比如我们需要开发一个视频播放组件,组件需要跟随当前的生命周期做启动播放、暂停播放与释放资源等相关操作。

如果是直接依赖Activity,那么需要在Activity的onCreate、onPause、onStop、onDestroy等生命周期中直接调用视频播放组件的相关API

如果业务比较简单,这样处理到无伤大雅。但是:

如果,视频播放组件在其它界面也有调用,会不会增加组件使用难度和操作风险?

按照之前的做法,就比较容易出现多处地方使用不一致的问题。“视频播放组件”作为通用的组件,但是处理生命周期的方法确实从像Activity等类中调用,就会出现关注点不分离的问题。

Activity应该关注于界面的渲染,而依赖于生命周期的组件在处理生命周期时候,因尽量的避免从外部调用,而是通过自己监听一个通用的生命周期回调,在自己的内部实现对生命周期的处理。这样Activity等只需要向需要生命周期的对象注入一个生命周期观察者进来,便可以完成之前的逻辑。而且能保证内部逻辑一致性

从官方注释可以得知:

  • 继承Lifecycle接口,便告知该对象是具备了生命周期,Activity、Fragment等都已实现
  • Lifecycle.Event.ON_CREATE 、 Lifecycle.Event.ON_START 、 Lifecycle.Event.ON_RESUME事件在LifecycleOwner的相关方法返回后调度
  • Lifecycle.Event.ON_PAUSE 、 Lifecycle.Event.ON_STOP 、 Lifecycle.Event.ON_DESTROY事件在调用LifecycleOwner的相关方法之前调度
  • 要观察生命周期事件,调用addObserver(LifecycleObserver)传递一个实现DefaultLifecycleObserver或LifecycleEventObserver的对象。

Lifecycle的组成部分

一、Lifecycle类

先介绍下Lifecycle中两个内部枚举类,State、Event。Event为分发的事件,State为宿主当前的状态。比如触发了某个Event,从而到达某个状态。

Event类

public enum Event {
    /**
     * LifecycleOwner#onCreate()执行后触发.
     */
    ON_CREATE,
    /**
     * LifecycleOwner#onStart()执行后触发.
     */
    ON_START,
    /**
     * LifecycleOwner#onResume()执行后触发.
     */
    ON_RESUME,
    /**
     * LifecycleOwner#onPause()执行前触发.
     */
    ON_PAUSE,
    /**
     * LifecycleOwner#onStop()执行前触发.
     */
    ON_STOP,
    /**
     * LifecycleOwner#onDestroy()执行前触发.
     */
    ON_DESTROY,   
 }

State类

public enum State {
    /**
     * LifecycleOwner 的销毁状态。在此事件之后,此生命周期将不再派发任何事件。
     */
    DESTROYED,

    /**
     * LifecycleOwner 的初始化状态。
     */
    INITIALIZED,

    /**
     * 为 LifecycleOwner 创建状态。
     * 在onCreate调用之后;
     * 就在onStop通话之前。
     */
    CREATED,

    /**
     * LifecycleOwner 的启动状态。
     * 在onStart调用之后;
     * 在onPause调用之前
     */
    STARTED,

    /**
     * LifecycleOwner 的恢复状态。对于android.app.Activity ,
     * 在调用onResume后达到此状态
     */
    RESUMED; 
}

对State中状态的理解

  • DESTROYED : 执行了OnDestroy方法后,到达的状态,该状态不会再进入到其他任何状态
  • INITIALIZED : 初始化状态,对象已经状态但并没有走到onCreate方法
  • CREATED : 不可见不可操作状态
  • STARTED : 可见但不可操作状态
  • RESUMED : 可见可操作状态

对于Event与State的关系,先看下官方的转换图

Event与State转换.jpg

在分析完Lifecycle中的枚举类,再回到Lifecycle本身的定义,如下。Lifecycle只是定义了对观察者的存储操作。

public abstract class Lifecycle {

    /**
     *方法被隐藏,用处存储Lifecycle对应的Scope对象
     */
    AtomicReference<Object> mInternalScopeRef = new AtomicReference<>();

    /**
     * 增加观察者
     */
    public abstract void addObserver(@NonNull LifecycleObserver observer);

    /**
     * 移除观察者
     */
    public abstract void removeObserver(@NonNull LifecycleObserver observer);

    /**
     * 获取当前状态
     */
    public abstract State getCurrentState();

二、LifecycleObserver

生命周期观察者,所有需要监听宿主生命周期状态,都需要继承接口。LifecycleObserver只是空接口,无定义方法。

子类有FullLifecycleObserver等

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);
}

三、LifecycleOwer

具有 Android 生命周期的类。自定义组件可以使用这些事件来处理生命周期更改,而无需在 Activity 或 Fragment 内实现任何代码。

public interface LifecycleOwner {
    /**
     * Returns the Lifecycle of the provider.
     *
     * @return The lifecycle of the provider.
     */
    @NonNull
    Lifecycle getLifecycle();
}

四、LifecycleRegistry

Lifecycle的实现类,可以处理多个观察者的Lifecycle实现。Activity、Fragment内部都是由LifecycleRegistry来分发事件和状态

具体讲解,见下面

Lifecycle原理

先来根据Lifecycle的功能,猜测下大致原理。

首先使用Lifecycle是为了可以感知宿主的生命周期,那么Event的源头在哪了?又是怎么分发处理的了?

在没有Lifecycle之前,我们都是在Activity、Fragment等宿主的onCreate等生命周期来分发生命状态的,那么Lifecycle肯定也是监听Activity等宿主的生命周期回调,来作为触发源的。

加上之前说过的LifecycleRegistry,该对象是Lifecycle的实现类,其中保存了所有生命周期的观察者,那么状态的处理和最终的分发,也一定是经过LifecycleRegistry遍历调用实现的。

到这有了两个具体的问题?

  • Lifecycle是如何监听宿主的生命周期的?
  • Lifecycle是如何完成生命状态的转换和分发的?

一、Lifecycle监听宿主的生命周期

Activity中监听生命周期

Activity继承关系中,最早是ComponentActivity继承了LifecycleOwner,也就是说,如果你的视图是直接继承自Activity是能够使用感应型的Lifecycle。


// 初始化LifecycleRegistry对象
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);


@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    // Restore the Saved State first so that it is available to
    // OnContextAvailableListener instances
    mSavedStateRegistryController.performRestore(savedInstanceState);
    mContextAwareHelper.dispatchOnContextAvailable(this);
    super.onCreate(savedInstanceState);
    // 通过ReportFragment处理
    ReportFragment.injectIfNeededIn(this);
    if (mContentLayoutId != 0) {
        setContentView(mContentLayoutId);
    }
}

可知,LifecycleRegistry是收集被观察者的容器,并在Activity的onCreate时候,委托ReportFragment来实现生命周期的处理。

接下来看下ReportFragment中的处理

public static void injectIfNeededIn(Activity activity) {
    if (Build.VERSION.SDK_INT >= 29) {
        // On API 29+, we can register for the correct Lifecycle callbacks directly
        LifecycleCallbacks.registerIn(activity);
    }
    // Prior to API 29 and to maintain compatibility with older versions of
    // ProcessLifecycleOwner (which may not be updated when lifecycle-runtime is updated and
    // need to support activities that don't extend from FragmentActivity from support lib),
    // use a framework fragment to get the correct timing of Lifecycle events
    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();
    }
}

如果API的版本 大于等于 29,则使用LifecycleCallbacks这种方式。如果小于29,则通过添加一个透明的ReportFragment来监听生命周期。

1)API >= 29

接下来先看下API大于等于29的情况

因为29以上版本,才增加了ActivityLifecycleCallbacks这种监听方案。

ActivityLifecycleCallbacks是Application的一个内部类。它的观察者都保存在ComponentActivity对象中,当执行Activity的生命方法时候,会被调用。

@RequiresApi(29)
static class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks {

    static void registerIn(Activity activity) {
        activity.registerActivityLifecycleCallbacks(new LifecycleCallbacks());
    }

    @Override
    public void onActivityCreated(@NonNull Activity activity,
            @Nullable Bundle bundle) {
    }

    @Override
    public void onActivityPostCreated(@NonNull Activity activity,
            @Nullable Bundle savedInstanceState) {
        dispatch(activity, Lifecycle.Event.ON_CREATE);
    }

    @Override
    public void onActivityStarted(@NonNull Activity activity) {
    }

    @Override
    public void onActivityPostStarted(@NonNull Activity activity) {
        dispatch(activity, Lifecycle.Event.ON_START);
    }

    @Override
    public void onActivityResumed(@NonNull Activity activity) {
    }

    @Override
    public void onActivityPostResumed(@NonNull Activity activity) {
        dispatch(activity, Lifecycle.Event.ON_RESUME);
    }

    @Override
    public void onActivityPrePaused(@NonNull Activity activity) {
        dispatch(activity, Lifecycle.Event.ON_PAUSE);
    }

    @Override
    public void onActivityPaused(@NonNull Activity activity) {
    }

    @Override
    public void onActivityPreStopped(@NonNull Activity activity) {
        dispatch(activity, Lifecycle.Event.ON_STOP);
    }

    @Override
    public void onActivityStopped(@NonNull Activity activity) {
    }

    @Override
    public void onActivitySaveInstanceState(@NonNull Activity activity,
            @NonNull Bundle bundle) {
    }

    @Override
    public void onActivityPreDestroyed(@NonNull Activity activity) {
        dispatch(activity, Lifecycle.Event.ON_DESTROY);
    }

    @Override
    public void onActivityDestroyed(@NonNull Activity activity) {
    }
}

ActivityLifecycleCallbacks中定义了相关的生命方法,对于Activity只需要注入一个生命周期的观察者,便可以监听到当前Activity的生命周期。

从上述接口的方法可知,ON_CREATE、ON_START、ON_RESUME是在执行了对应的生命周期之后才分发的。而ON_PAUSE、ON_STOP、ON_DESTROY是在生命周期方法之前分发。

回调的对应方法中,调用了同象的spatch方法,最终走到的了LifecycleRegistry的handleLifecycleEvent来处理分发事件。具体的分发下一章再说

public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    enforceMainThreadIfNeeded("handleLifecycleEvent");
    moveToState(event.getTargetState());
}

2)API < 29

API 在29之前采用的是,添加一个无界面的ReportFragment,该Fragment和Activity具有同样的生命周期

下面是ReportFragment的生命周期回调,而可知API大于29还是小于29,实现的功能都是一样的,没有区别。

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    dispatchCreate(mProcessListener);
    dispatch(Lifecycle.Event.ON_CREATE);
}

@Override
public void onStart() {
    super.onStart();
    dispatchStart(mProcessListener);
    dispatch(Lifecycle.Event.ON_START);
}

@Override
public void onResume() {
    super.onResume();
    dispatchResume(mProcessListener);
    dispatch(Lifecycle.Event.ON_RESUME);
}

@Override
public void onPause() {
    super.onPause();
    dispatch(Lifecycle.Event.ON_PAUSE);
}

@Override
public void onStop() {
    super.onStop();
    dispatch(Lifecycle.Event.ON_STOP);
}

@Override
public void onDestroy() {
    super.onDestroy();
    dispatch(Lifecycle.Event.ON_DESTROY);
    // just want to be sure that we won't leak reference to an activity
    mProcessListener = null;
}

Fragment中监听生命周期

对于Fragment也和Activity类型,都是通过原生的生命周期方法中去触发,最终都是到LifecycleRegistry.handleLifecycleEvent中处理。

public class Fragment implements LifecycleOwner {

    LifecycleRegistry mLifecycleRegistry;

    void performCreate(Bundle savedInstanceState) {
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
    }

    void performStart() {
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
    }

    void performResume() {
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
    }

    void performPause() {
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
    }

    void performStop() {
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
    }

    void performDestroy() {
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
    }
}

问题 : 为什么在API 29版本之后,就不采用添加ReportFragment这种方式来支持Lifecycle?

两种Fragment,ReportFragment采用的android.app.Fragment,现在已经被弃用了。而我们现在经常使用的android.support.v4.app.Fragment是support包下面的。

所以为了以后代码的兼容,放弃了ReportFragment这种方式。

二、LecycleRegistry Event事件处理与分发

在ComponentActivity和Fragment等类中,都对LifecycleRegistry进行了初始化。

通过虚引用保存LifecycleOwner,从而获取Lifecycle对象

private LifecycleRegistry(@NonNull LifecycleOwner provider, boolean enforceMainThread) {
    mLifecycleOwner = new WeakReference<>(provider);
    mState = INITIALIZED;
    mEnforceMainThread = enforceMainThread;
}

addObserver 添加观察者

public void addObserver(@NonNull LifecycleObserver observer) {
    enforceMainThreadIfNeeded("addObserver");
    // 默认的状态
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    // 
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

    if (previous != null) {
        return;
    }
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    if (lifecycleOwner == null) {
        // it is null we should be destroyed. Fallback quickly
        return;
    }

    boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
    State targetState = calculateTargetState(observer);
    mAddingObserverCounter++;
    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();
        // mState / subling may have been changed recalculate
        targetState = calculateTargetState(observer);
    }

    if (!isReentrance) {
        // we do sync only on the top level.
        sync();
    }
    mAddingObserverCounter--;
}
  • 将观察者包装成ObserverWithState对象,这是为了观察者来源的不一致性,有的是调用方法注入的,有的是通过注解方法。观察者的对象也可以不一致,对此封装成统一的对象来解决差异性

  • 将Observer保存到mObserverMap中,同一个观察者不能多次保存。

  • 然后再通过循环,将被观察者的状态和宿主的状态保持一致。比如说宿主的状态为On_Resume状态,那么对于一个新增加的观察者,那么需要依次的分发on_Create、on_Start、on_Resume事件,从而将观察者和宿主状态保持一致。

removeObserver

remove就是简单的移除观察者,没有额外的其他流程

ObserverWithState 对象

上文添加观察者提过ObserverWithState对象,把传入的观察者包装成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)是将Observer转成LifecycleEventObserver入口方法

@NonNull
@SuppressWarnings("deprecation")
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);
    }

    if (isLifecycleEventObserver) {
        return (LifecycleEventObserver) object;
    }

    final Class<?> klass = object.getClass();
    int type = getObserverConstructorType(klass);
    if (type == GENERATED_CALLBACK) {
        List<Constructor<? extends GeneratedAdapter>> constructors =
                sClassToAdapters.get(klass);
        if (constructors.size() == 1) {
            GeneratedAdapter generatedAdapter = createGeneratedAdapter(
                    constructors.get(0), object);
            return new SingleGeneratedAdapterObserver(generatedAdapter);
        }
        GeneratedAdapter[] adapters = new GeneratedAdapter[constructors.size()];
        for (int i = 0; i < constructors.size(); i++) {
            adapters[i] = createGeneratedAdapter(constructors.get(i), object);
        }
        return new CompositeGeneratedAdaptersObserver(adapters);
    }
    return new ReflectiveGenericLifecycleObserver(object);
}

从上述代码来看,根据传入的观察者类型,返回对应的适配器,根据具体的观察者的特点,来调用方法。

比如通过注解注入的观察者,需要解析并特殊的调用。

handleLifecycleEvent 事件分发流程

从LifecycleRegistry代码中得知,处理状态有两入口方法。但最终回执行moveToState方法,传入的是当前宿主的状态。

@MainThread
public void setCurrentState(@NonNull State state) {
    enforceMainThreadIfNeeded("setCurrentState");
    moveToState(state);
}

public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    enforceMainThreadIfNeeded("handleLifecycleEvent");
    moveToState(event.getTargetState());
}
private void moveToState(State next) {
// 如果设置状态和当前状态相等则不处理
    if (mState == next) {
        return;
    }
    mState = next;
    // 正在处理中或者没有新添加的观察者,也不需要处理
    if (mHandlingEvent || mAddingObserverCounter != 0) {
        mNewEventOccurred = true;
        // we will figure out what to do on upper level.
        return;
    }
    mHandlingEvent = true;
    // 同步状态(核心代码)
    sync();
    mHandlingEvent = false;
}

moveToState方法中,先做了些前置的校验,校验通过后进入sync方法来同步状态。sync作用便是同步新添加的观察者和宿主状态。

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 (!isSynced()) {
        mNewEventOccurred = false;
        // 判断当前的状态需不需要回退,比如当前的状态是STARTED状态,
        // 而最早添加的观察者的状态是Resume。那就需要下发一个On_Pause事件
        if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
            backwardPass(lifecycleOwner);
        }
        
        // 和backwardPass功能想法,backwardPass是回退状态。forwardPass是前置状态
        Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
        if (!mNewEventOccurred && newest != null
                && mState.compareTo(newest.getValue().mState) > 0) {
            forwardPass(lifecycleOwner);
        }
    }
    mNewEventOccurred = false;
}

以backwardPass方法举例,看下状态是如何同步的。

private void backwardPass(LifecycleOwner lifecycleOwner) {
    // 1、收集待处理的观察者队列
    Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
            mObserverMap.descendingIterator();
    while (descendingIterator.hasNext() && !mNewEventOccurred) {
        Map.Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
        ObserverWithState observer = entry.getValue();
        // 2、状态不一致 && 没有新的事件进入 && 观察者没有被移除
        while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
                
            // 寻找到下一个观察者当前状态的进入下一个回退状态的事件
            Event event = Event.downFrom(observer.mState);
            if (event == null) {
                throw new IllegalStateException("no event down from " + observer.mState);
            }
            pushParentState(event.getTargetState());
            // 在处理完需要回退的观察者时候,需要再对向前状态处理。因为可能在处理的过程中,新进来了新的事件或者观察者。
            // 导致整个观察者队列,有向前处理的状态又有向后处理的状态
            observer.dispatchEvent(lifecycleOwner, event);
            popParentState();
        }
    }
}

FastSafeIterableMap 数据结构:

FastSafeIterableMap是用来保存Observer观察者的数据结构,虽然名称包含Map,但是他继承的是Iterator接口,而非是Map结构。

从源码中可知,FastSafeIterableMap继承至SafeIterableMap,SafeIterableMap再继承自Iterator接口,SafeIterableMap里面采用链表的结构存储数据,他们都是非线程安全的数据结构。

而为了查找的效率,FastSafeIterableMap中增加了Map的成员变量保存数据。所以在每份数据在FastSafeIterableMap中都存储两份,正常情况下监听生命周期的观察者数量较少,不会有问题

小结

  1. Lifecycle是一个可感知生命周期的组件,是Jetpack提供的基础组件。目的是为了关注点分离,解决和宿主的耦合性。
  2. State.CREATE状态为不可见&失焦不可操作,State.PAUSE状态为可见&失焦不可操作,State.RESUME状态为可见&可操作。
  3. 在API < 29 之前,采用的是ReportFragment监听Activity生命周期,29之后,使用注入Application.ActivityLifecycleCallbacks生命周期回调
  4. 可以采用注解或者手动继承LifecycleObserver接口,最终注入进来的会包装成ObserverWithState,事件分发会统一走dispatchEvent来分发处理。所有的观察者会包装成LifecycleEventObserver,解决回调方式的差异性。
  5. 事件分发的处理逻辑在LifecycleRegistry类中,只有当宿主状态变更或者新增观察者两种情况,才会给观察者下发状态。