Android架构灵魂组件Lifecycle的生命周期机制详解

前言:写作就跟生活一样,是一趟发现之旅。

前言

在早期 Andorid 架构中,生命周期的事件监听和状态查询,我们需要自定义一套提供侦测功能的 Activity/Fragment 基类及回调接口,在 Activity/Fragment 的生命周期方法中实现依赖组件的操作,在外部进行事件监听和状态查询。这种模式会导致代码条理性很差而且会扩散错误。

在 Lifecycle 引入后,可以避免在 Activity/Fragment 生命周期方法内写太多的业务逻辑处理代码,这样可以使我们的业务逻辑更加解耦。有助于您编写出更有条理且往往更精简的代码,此类代码更易于维护。

什么是Lifecycle

Lifecycle 是一个具备宿主生命周期感知能力的组件。它持有组件(Activity/Fragment)生命周期状态信息,并且允许其观察者监听宿主生命周期状态变化。

一、Lifecycle的使用

在 build.gradle 文件中添加依赖:

implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.5.1"
implementation "androidx.lifecycle:lifecycle-common:2.5.1"

使用 Lifecycle 观察宿主状态有三种实现方式。

1.继承LifecycleObserver

第一种是实现 LifecycleObserver 接口,采用注解方式,使用 @OnLifecycleEvent 标记自定义的方法以实现回调。

//1.自定义LifecycleObserver观察者,用注解声明每个方法观察宿主的状态
public class MyLifecycleObserver implements LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void onStart(@NotNull LifecycleOwner owner) {

    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void onStop(@NotNull LifecycleOwner owner) {

    }
}

//2.宿主中注册观察者,观察宿主生命周期状态变化
class MyFragment extends Fragment {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MyLifecycleObserver observer = new MyLifecycleObserver();
        getLifecycle().addObserver(observer);
    }
}

实现 LifecycleObserver 接口,只需要在指定方法上面标记注解,来观察宿主的生命周期,注解里面标记着生命周期事件类型就可以了。然后在宿主注册这个 LifecycleObserver,它不需要销毁的时候进行反注册。

2.实现DefaultLifecycleObserver接口

第二种方式:定义一个类,实现 DefaultLifecycleObserver 接口,里面提供了完整的生命周期事件,为所有的生命周期事件都定义了对应的回调方法。它实现了 FullLifecycleObserver 接口,使用了 default 关键字空实现了各个方法。

class MyFullLifeObserver : DefaultLifecycleObserver {

    override fun onCreate(owner: LifecycleOwner) {}

    override fun onStart(owner: LifecycleOwner) {}

    override fun onResume(owner: LifecycleOwner) {}

    override fun onPause(owner: LifecycleOwner) {}

    override fun onStop(owner: LifecycleOwner) {}

    override fun onDestroy(owner: LifecycleOwner) {}
}

使用 DefaultLifecycleObserver 后,就需要把注解实现相关逻辑移除。即使保留注解,由于 Lifecycling 的处理逻辑(系统架构逻辑中所有传入的观察者都会经过 Lifecycling 处理,下面会讲解到),任何 FullLifecycleObserver 的实现类 (即包括DefaultLifecycleObserver) 内部所有的 @OnLifecycleEvent 注解都会失效。

3.实现LifecycleEventObserver

第三种方式:实现 LifecycleEventObserver,它是 LifecycleObserver 的子接口。只有一个 onStateChanged 方法,以 Lifecycle.Event 入参提供事件区分的形式,进行统一方法回调。

interface LifecycleEventObserver : LifecycleObserver {
    // 宿主生命周期变化的事件都会通知到这个方法
    fun onStateChanged(owner: LifecycleOwner?, event: Lifecycle.Event?)
}

//继承自LifecycleEventObserver,复写onStateChanged方法
class MyLifecycleEventObserver : LifecycleEventObserver {
    override fun onStateChanged(owner: LifecycleOwner?, event: Lifecycle.Event?) {
        //需要自行判断Event是onStart还是onStop
    }
}

无论哪一种方法都需要在宿主中注册观察者。推荐使用第二种和第三种方式,第一种不推荐使用。

二、Lifecycle 组件架构

为下面更好深入理解原理,我们先来简单了解下 Lifecycle 组件中几个重要的类:

  • Lifecycle(生命周期) :一个核心抽象类,用于存储有关组件(如 activity/fragment 的生命周期状态的信息,并允许其他对象观察此状态。继承该类的子类,表示本身是一个 具有Android生命周期特性 的对象。

  • LifecycleOwner:核心接口,Lifecycle 持有者,该接口的实现类表示能够为外部提供Lifecycle实例。具有 Android 生命周期的类。这些事件可以被自定义组件用来处理生命周期的变化,而不需要在 Activity/Fragment 中实现任何代码。

  • LifecycleRegistry:核心类,Lifecycle 的实现类,可以处理多个观察者。实现 Lifecycle 定义生命周期观察订阅,生命周期查询的方法。还实现了架构中,生命周期变化时触发的自身状态处理和相关对观察者的订阅回调的逻辑。

  • LifecycleObserver:观察者,将一个类标记为生命周期观察者。实现该接口的类,通过注解的方式,可以通过被 LifecycleOwner 类的 addObserver() 方法注册,LifecycleObserver 便可以观察到 LifecycleOwner 的生命周期事件。

  • State :当前生命周期所处的状态。

  • Event :当前生命周期改变对应的事件。从框架和 Lifecycle 类分派的生命周期事件。这些事件对应到 activity/fragment 中的回调事件。

LifecyclerOwner、Lifecycle、LifecyleRegistry 和 Observer 的关系如下图:

Android架构灵魂组件Lifecycle的生命周期机制详解_第1张图片

一般来说宿主代表着 Activity/Fragment,都实现了 LifecyclerOwner 接口;那么每个宿主必须复写 getLifecycle(),并且返回一个 Lifecycle 对象,这个 Lifecycle 对象实际上是LifecycleRegistry,只不过它采用的是面向接口的编程方式,我们对 LifecycleRegistry 注册 Observer 的时候,可以是 LifecycleObserver,FullLifecyclerOberver,LifecyclerEventObserver。

三、Lifecycle 原理剖析

系统框架中,LifecycleOwner 接口的实现类为 ComponentActivity 和 Fragment,两者提供的 Lifecycle 对象,是系统框架实现中 Lifecycle 的唯一子类 LifecycleRegistry。

1.Fragment是如何实现Lifecycle的

public class Fragment implements LifecycleOwner {
    // 创建LifecycleRegistry 并且把this传递进去
    LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    @Override
    public Lifecycle getLifecycle() {
        //2.复写自LifecycleOwner,所以必须new LifecycleRegistry对象返回
        return mLifecycleRegistry;
    }
    //······
}

Fragment 内 Lifecycle 核心代码片段,实现了 LifecycleOwner 接口,它表示生命周期宿主,持有生命周期(Lifecycle对象),该接口的生命周期的改变会被其注册的观察者 LifecycleObserver 观察到并触发其对应的事件。

必须复写 getLifecycle() 这个方法,返回的实际是 mLifecycleRegistry,说明 Lifecycle 是 LifecycleRegistry 的父类,这是一种面向接口的编程思想。

public class Fragment implements LifecycleOwner {
    //······
    void performCreate(Bundle savedInstanceState) {
        //······
        onCreate(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() {
        mChildFragmentManager.dispatchDestroy();
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
        //······
     }
}

我们注册 Lifecycle 的时候,实际上都注册到 LifecycleRegistry 里面去了。通过 handleLifecycleEvent() 分发自己的状态到每个观察者,从而实现观察生命周期实现变化的能力。看起来简单实际上 Lifecycle 在分发生命周期的时候并不简单,所有逻辑重点都在 LifecycleRegistry。

Fragment 是如何派发生命周期的?也就是它会在自己生命周期里面,让 LifecycleRegistry 去分发生命周期事件,给每一个观察者。但是 Activity 中并不是这么做的。

2.Activity是如何是实现Lifecycle的

Activity 实现 Lifecycle 的核心源码,需要来到 ComponentActivity 里面,同样也是实现了 LifecycleOwner 接口:

public class ComponentActivity extends Activity implements LifecycleOwner {
    private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    //复写getLifecycle(),返回LifecycleRegistry对象
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //往Activity上添加一个fragment,用以报告生命周期的变化
        //目的是为了兼顾不是继承自AppCompactActivity的场景
        ReportFragment.injectIfNeededIn(this);
    }
}

与上面 Fragment 的实现类似,它实现了 LifecycleOwner,表示一个生命周期的宿主,必须实现 getLifecycle() 方法,返回一个 Lifecycle,也就是 LifecycleRegistry。

但是在 ComponentActivity 里面并没有在它的每个生命周期方法里面把它的状态分发给一个观察者,但是在 onCreate() 方法里面调用 ReportFragment.injectIfNeededIn(this) 这种做法实际上是往自己里面添加了一个不可见的 Fragment,专门用于报告分发给每个观察者。

public class ReportFragment extends Fragment {
    public static void injectIfNeededIn (Activity activity) {
        if (Build.VERSION.SDK_INT >= 29) {
            // API 29 以上可以直接注册正确的生命周期回调
            activity.registerActivityLifecycleCallbacks(
                new LifecycleCallbacks ()
            );
        }
        // 兼容API 29之前的,需要支持直接继承Activity的,使用Fragment来正确获得生命周期事件
        android.app.FragmentManager manager = activity . getFragmentManager ();
        if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
            manager.beginTransaction().add(new ReportFragment (), REPORT_FRAGMENT_TAG).commit();
            manager.executePendingTransactions();
        }
    }
} 

所以 Activity 事件的分发是依靠 ReportFragment 来完成的。

  • API 29 以下: 主要是通过 ReportFragment 将自身添加到 Activity 中实现。

  • API 29 及以上:Activity 中增加一组 ActivityLifecycleCallbacks 的相关方法,可以直接通过注册 ActivityLifecycleCallbacks 观察生命周期。

ComponentActivity 为什么这么做而不直接在 Activity 内部直接分发呢?主要是为了兼顾不是继承自 AppCompatActivity 的场景。有可能是直接继承自 Activity,然后自己实现了 Lifecycle 接口。

public class ReportFragment extends Fragment {
    // 增加dispatch重载,尝试获取Activity中的LifecycleRegistry并调用 handleLifecycleEvent
    static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
        if (activity instanceof LifecycleRegistryOwner) {
            ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
            return;
        }

        if (activity instanceof LifecycleOwner) {
            Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
            if (lifecycle instanceof LifecycleRegistry) {
                ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
            }
        }
    }
    // 2.各个生命周期方法里面都调用了dispatch()方法
    @Override
    public void onStart() {
        super.onStart();
        dispatch(Lifecycle.Event.ON_START);
    }

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

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

    // 3.拿到Activity的Lifecycle对象,把当前的事件分发给每个观察者
    private void dispatch(@NonNull Lifecycle.Event event) {
        if (Build.VERSION.SDK_INT < 29) {
            // 在API 29之前从ReportFragment分派事件。
            // 在API 29+上,由reportfragment.injectifneededdin中添加的activitylifecyecallbacks处理
            dispatch(getActivity(), event);
        }
    }
}

为了前向兼容,ReportFragment 依然会被添加到 Activity,并在 dispatch() 中增加过滤避免出现二次调用。

ReportFragment 会在侦测到 Activity 生命周期变化的时候调用 LifecycleRegistry.handleLifecycleEvent() 传入对应的状态。这时候会有一个类 LifecycleDispatcher:

//挂钩到Activity的回调并进行观察
class LifecycleDispatcher {
    private static AtomicBoolean sInitialized = new AtomicBoolean(false);

    static void init(Context context) {
        ((Application) context.getApplicationContext())
                .registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
    }

    static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {
        @Override
        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            // 监听到每个Activity打开的事件
            ReportFragment.injectIfNeededIn(activity);
        }
    }
}

在它的 init() 方法里面调用了 registerActivityLifecycleCallbacks(),这里就能监察到每个 Activity 打开的事件,会再次利用 ReportFragment.injectIfNeededIn(activity),也就是说往每个 Activity 里面注册一个 ReportFragment,用于分发和报告当前宿主的生命周期到每个观察者,它这里是以一个切面编程的方式注入了一个 Fragment 对象,尽管我们是继承子 Activity,只要你实现了 LifecycleOwner 的接口,也能具备生命周期分发的能力。所以 Activity 生命周期分发的功能提取到 ReportFragment 里面,主要是为了不是继承自 AppCompatActivity 的场景。

到这里 Activity/Fragment 各自是如何实现 Lifecycle 能力的已经分析完成。但是无论如何生命周期能力都是依赖 LifecycleRegistry 来完成的。

3.LifecycleRegistry 源码分析

它是 Lifecycle 的实现,可以处理多个观察者。生命周期事件分发都是依靠 LifecycleRegistry 来完成的。先从添加观察者方法开始:

@Override
public void addObserver(@NonNull LifecycleObserver observer) {
    enforceMainThreadIfNeeded("addObserver");
    // 1.初始化状态,当前宿主的状态
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    // 2.将observer封装成 ObserverWithState,是一个拥有宿主状态的观察者
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    // 添加到Map集合中
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

    boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
    // 3.计算出它应该到达的状态,也就是当前宿主的状态
    State targetState = calculateTargetState(observer);
    mAddingObserverCounter++;
    // 4.在while()循环中,会让当前的观察者的状态从init状态前进到当前宿主的状态
    //Observer的状态与targetState比较,如果小于0说明观察者的状态还没有到达targetState的状态
    while ((statefulObserver.mState.compareTo(targetState) < 0
            && mObserverMap.contains(observer))) {
        pushParentState(statefulObserver.mState);
        // 5.让Observer的状态前进到targetState
        final Event event = Event.upFrom(statefulObserver.mState);
        // 6. 分发事件
        statefulObserver.dispatchEvent(lifecycleOwner, event);
        popParentState();
        // 从新计算mState
        targetState = calculateTargetState(observer);
    }

    if (!isReentrance) {
        //同步状态
        sync();
    }
}

在 addObserver(observer) 里面,初始化状态,并且把observer封装成一个ObserverWithState,一个拥有宿主状态的观察者,然后添加到Map集合当中。

这里主要做了四件事

  1. 初始化状态,将 observer 封装成 ObserverWithState,是一个拥有初始状态的观察者;

  2. 计算出它应该到达的状态,也就是当前宿主的状态

  3. while 循环会让当前的观察者的状态从 INITIALIZED 状态前进到当前宿主的状态,Observer 的状态小于 targetState 说明观察者的状态还没有到达 targetState 的状态,那么就会让 Observer 的状态前进到 targetState;

  4. Observe 调用 dispatchEvent() 分发事件。

每个步骤都很重要,我们来一一分析:

4.状态与事件

State 是一个枚举,表示宿主的状态,但是宿主的状态和宿主的生命周期不是同一个概念。

public enum State {
    // 宿主的销毁状态,onDestory()之后
    DESTROYED,
    // 宿主的初始状态,onCreate()之前
    INITIALIZED,
    // 宿主的创建状态,onCreate()之后,onStop()之前
    CREATED,
    // 宿主的启动状态,onStart()之后,onPasue()之前
    STARTED,
    // 恢复状态,onResume()之后
    RESUMED;
}

比如宿主切换到后台,会执行 onPause() 方法,那么宿主的状态是什么状态?再从后台切回前台会执行 onStart() 再执行 onResum(),所以切换到后台的时候,执行了 onPause 这个事件,它的状态会变成 STARTED 的状态。可以看到它是没有 PAUSE 状态的。

这里还定义了 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,
     //可以匹配所有事件的常量
    ON_ANY
}

宿主生命周期与宿主状态关系图

Android架构灵魂组件Lifecycle的生命周期机制详解_第2张图片

宿主在创建之初肯定是处于 INITIALIZED 状态,执行了 onCreate() 方法之后就会进入 CREATED 状态,接着执行了 onStart() 方法之后就会进入 STARTED 状态,执行了 onResume() 就会进入 RESUMED 状态,这是生命周期前进的过程,生命周期倒退过程同理。这里就是宿主的生命周期状态和事件完整的流程。

5.状态比较和升降级

回到 addObserver() 方法中:

@Override
public void addObserver(@NonNull LifecycleObserver observer) {
    enforceMainThreadIfNeeded("addObserver");
    // 1.获取observer需要设置的初始状态
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    // 2.将observer封装成 ObserverWithState,并绑定初始的生命周期状态
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    // 添加到Map集合中
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

    boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
    // 3.计算出它应该到达的目标状态
    State targetState = calculateTargetState(observer);
    mAddingObserverCounter++;
    // 4.在while()循环中,会让当前的观察者的状态从init状态前进到目标状态
    //Observer的状态与targetState比较,如果小于0说明观察者的状态还没有到达targetState的状态
    while ((statefulObserver.mState.compareTo(targetState) < 0
            && mObserverMap.contains(observer))) {
        pushParentState(statefulObserver.mState);
        // 5.让Observer的状态升级到targetState
        final Event event = Event.upFrom(statefulObserver.mState);
        // 6. 分发事件,同步状态
        statefulObserver.dispatchEvent(lifecycleOwner, event);
        popParentState();
        // 重新计算mState
        targetState = calculateTargetState(observer);
    }

    if (!isReentrance) {
        //同步状态
        sync();
    }
}

在初始状态中,只要不是在 onDestory 注册的 Observer,每个观察者的初始状态都是 INITIALIZED 状态。在 while 循环中,会让当前的观察者的状态从 INITIALIZED 状态升级到目标状态,如果观察者的状态小于目标状态,就会通过 Event.upFrom() 方法让生命周期升级。

比如我们在 onResme() 方法中注册一个观察者,那么它会接收到哪几种状态呢?INITIALIZED、ONSTART、ONRESUME 它都会有,这个逻辑就在 while 循环里面,先通过 calculateTargetState(observer) 计算出它应该到达的目标状态,也就是当前宿主的状态,然后会拿 Observer 的状态比较,如果小于0说明观察者的状态还没有到达 targetState 的状态,那么就会让 Observer 的状态升级到 targetState。那么是如何进行升级的呢?

// 计算传入状态升级所对应的事件
public static Event upFrom(@NonNull State state) {
    switch (state) {
        case INITIALIZED:
            return ON_CREATE;
        case CREATED:
            return ON_START;
        case STARTED:
            return ON_RESUME;
        default:
            return null;
    }
}

离开当前的状态到达更高的状态,事件的状态从较低向上升级。在 INITIALIZED 状态中接收的是 on_Create 事件,然后来到 dispatchEvent() 方法里面:

static class ObserverWithState {
    // 当前状态
    State mState;
    // Observer封装
    LifecycleEventObserver mLifecycleObserver;

    ObserverWithState(LifecycleObserver observer, State initialState) {
        mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
        mState = initialState;
    }

    //事件分发逻辑
    void dispatchEvent(LifecycleOwner owner, Event event) {
        //根据Event获取目标状态
        State newState = event.getTargetState();
        // 获取最小状态
        mState = min(mState, newState);
        // 状态改变回调
        mLifecycleObserver.onStateChanged(owner, event);
        // 更新当前状态
        mState = newState;
    }
}

会根据 Event 反推出目标状态,在 event.getTargetState() 里面,如果 Event 事件是 ON_CREATE 那么就会到达 State.CREATED 的状态,在调用 mLifecycleObserver.onStateChanged(owner, event) 之后,mState = newState状态就变成新的状态,前进了一步,从 INITIALIZED 状态变成了 CREATED 状态。

// 获取事件目标状态
public State getTargetState() {
    switch (this) {
        // 如果事件是 ON_CREATE或者ON_STOP,那么状态会到达State.CREATED
        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;
    }
}

它在分发事件的时候是根据观察者的状态推导出分发的事件,然后再根据分发的事件推导出观察者的状态,在这个方法执行完后,会再次回到While()循环中,再次进行观察者状态与目标状态比较,当前状态 mState 已经变成 CREATE, 如果 targetState 是 INITIALIZED,那么就实现了状态的升级。

但是如果 targetState 是 RESUME,while循环比较还是小于0的,则会再次调用 Event.upFrom(mState) 和 dispatchEvent() 方法,将状态升级到 STATED,继续循环升级到 RESUME,依此类推,mState = newState状态就变成新的状态 RESUME。直到观察者的状态和宿主的状态达到一致,然后退出While()循环,如下图

  • 添加Observer时,完整的生命周期事件分发

ObserverWithState 被创建之初状态为 INITIALIZED,如果在宿主的 onResume() 生命周期注册一个 Observer,会把宿主的 onCreate,onStart,onResume 都分发给 Observer:

Android架构灵魂组件Lifecycle的生命周期机制详解_第3张图片

直到 Observer 的状态和宿主的状态对齐为止,而不是直接从 INITIALIZED 状态直接分发一个 RESUME 直接到达 RESUME,目的因为我们可以在任何地方注册,并且可以接收到完整的接收事件,从而完成初始化,暂停,释放的工作。

这是添加观察者时的事件分发流程。

6.Lifecycle是如何分发宿主状态的

那么宿主的生命周期变化之后是如何分发给每一个观察者的?

根据上面 Activity/Fragment 源码分析,它会在每个生命周期方法里面执行handleLifecycleEvent(event)event.getTargetState()根据当前的事件推导出每个观察者目标的生命周期状态。

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

private void moveToState(State next) {
    if (mState == next) {
        return;
    }
    mState = next;
    mHandlingEvent = true;
    // 同步新状态事件
    sync();
    mHandlingEvent = false;
}

moveToState(next) 里面主要是做一些条件的判断,真正的状态同步是在 sync() 方法里面:

private void sync() {
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    //循环,直到isSynced()同步完成,所有观察者的状态都分发完,状态都与宿主的状态一致
    while (!isSynced()) {
        mNewEventOccurred = false;
        // 1.宿主的状态小于观察者状态,观察者状态进行降级
        if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
            //状态降级
            backwardPass(lifecycleOwner);
        }
        Entry newest = mObserverMap.newest();
        // 2. 宿主的状态大于观察者状态,观察者状态进行升级
        if (!mNewEventOccurred && newest != null
                && mState.compareTo(newest.getValue().mState) > 0) {
            // 状态升级
            forwardPass(lifecycleOwner);
        }
    }
    mNewEventOccurred = false;
}

isSynced() 判断这个接口里面注册的 Observer 是否所有观察者的状态都分发完成,都已经同步到跟宿主一致的状态。如果不是则进入状态判断:

  1. 宿主的状态小于观察者状态,观察者状态进行降级;

  2. 宿主的状态大于观察者状态,观察者状态进行升级。

如果宿主的状态小于观察者状态,这种发生在生命周期倒退的阶段,比如前台切换到后台,执行 onPause() 方法,宿主进入 STARED 状态,观察者还处于 RESUME 状态,backwardPass() 是让所有的观察者都倒退,和宿主一样的状态,并且分发相应的事件给他们,

private void backwardPass(LifecycleOwner lifecycleOwner) {
    Iterator> descendingIterator =
            mObserverMap.descendingIterator();
    // 循环遍历所有观察者
    while (descendingIterator.hasNext() && !mNewEventOccurred) {
        Map.Entry entry = descendingIterator.next();
        ObserverWithState observer = entry.getValue();
        // 循环对比单个观察者的状态,直到单个观察者同步到目标状态,观察者状态大于宿主状态,则将观察者状态降级处理
        while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            // 根据observer.mState 的状态降级,获取对应的Event事件
            Event event = Event.downFrom(observer.mState);

            pushParentState(event.getTargetState());
            // 分发相应的事件Event
            observer.dispatchEvent(lifecycleOwner, event);
            popParentState();
        }
    }
}

这里的核心逻辑就是遍历所有观察者,根据当前观察者的状态,计算出它应该分发哪一种事件,由于是生命周期的倒退,这里执行的是 Event.downFrom(observer.mState),也就是生命周期的降级:

// 计算传入状态降级所对应的事件
public static Event downFrom(@NonNull State state) {
    switch (state) {
        // 如果当前的状态是 CREATED,发生生命周期倒退就是执行了ON_DESTROY,返回ON_DESTROY事件
        case CREATED:
            return ON_DESTROY;
        case STARTED:
            return ON_STOP;
        case RESUMED:
            return ON_PAUSE;
        default:
            return null;
    }
}

如果观察者是 RESUME 状态,发生生命周期倒退,就会返回一个 ON_PAUSE 事件,如果是 STARTED 状态发生生命周期的倒退也就是返回 ON_STOP 事件。

然后根据返回的事件,调用 observer.dispatchEvent() 分发给它,根据上面的分析,还会当前的事件推导出目标的状态,然后赋值给 mState。

static class ObserverWithState {
    void dispatchEvent(LifecycleOwner owner, Event event) {
        //根据Event获取目标状态
        State newState = event.getTargetState();
        // 获取最小状态
        mState = min(mState, newState);
        // 状态改变回调
        mLifecycleObserver.onStateChanged(owner, event);
        // 更新当前状态
        mState = newState;
    }
}

backwardPass() 执行完之后,观察者的状态就会降级到和宿主一样的状态,直到集合里面的所有观察者的状态和宿主的一样为止。

private void sync() {
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    //所有观察者的状态都分发完,状态都与宿主的状态一致
    while (!isSynced()) {
        // ······
        Entry newest = mObserverMap.newest();
        // 2. 宿主的状态和Observe状态比较,宿主的状态大于观察者状态,观察者状态进行升级
        if (!mNewEventOccurred && newest != null
                && mState.compareTo(newest.getValue().mState) > 0) {
            // 状态升级
            forwardPass(lifecycleOwner);
        }
    }
    mNewEventOccurred = false;
}

同理,进入 sync() 的第二个判断条件,把当前宿主的状态和每个观察者的状态进行比较,如果大于0,生命周期前进(比如后台切换到前台),从 STARTES 状态切换到 RESUME 状态, forwardPass(lifecycleOwner) 逻辑与 backwardPass() 相似,只不过这是状态前进的过程,会调用 Event.upForm(observer.mState),根据当前观察者的状态在生命周期前进的时候计算出它应该分发哪一个事件。

private void forwardPass(LifecycleOwner lifecycleOwner) {
    Iterator> ascendingIterator =
            mObserverMap.iteratorWithAdditions();
    // 循环遍历所有观察者
    while (ascendingIterator.hasNext() && !mNewEventOccurred) {
        Map.Entry entry = ascendingIterator.next();
        ObserverWithState observer = entry.getValue();
        // 观察者状小于于宿主状态,则将观察者状态升级处理
        while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            pushParentState(observer.mState);
            // 根据mState状态升级,获取对应的分发事件Event
            final Event event = Event.upFrom(observer.mState);
            // 分发完后就和宿主达到一致的状态
            observer.dispatchEvent(lifecycleOwner, event);
            popParentState();
        }
    }
}

observer.dispatchEvent() 分发完就会与宿主达到一致的状态,直到 Observer 集合当中所有观察者与宿主的状态保持一致,并且退出这个循环。

到这里,宿主的生命周期和宿主状态的关系,每个生命周期变化的时候,都会分发相应的事件,并且根据这个事件推导出宿主的状态,遍历所有的观察者,让他们的状态也随之升级,或者降级,并且把本次事件分发给观察者。

7.如何区分LifecycleObserver的类型

那么这个事件它在分发的时候,是如何区分的 LifecycleObserver 还是 FullLifecycleObserver,亦或者是 LifecycleEventObserver 这三种类类型的?在 addObserver() 里面,每次注册一个 Observer 都会把它包装成一个 ObserverWithState:

static class ObserverWithState {
    State mState;
    LifecycleEventObserver mLifecycleObserver;
    //把传递进来的observer转换成LifecycleEventObserver
    ObserverWithState(LifecycleObserver observer, State initialState) {
        mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
        mState = initialState;
    }

    void dispatchEvent(LifecycleOwner owner, Event event) {
        State newState = getStateAfter(event);
        mState = min(mState, newState);
        // 分发事件
        mLifecycleObserver.onStateChanged(owner, event);
        mState = newState;
    }
}

它把传递进来的 observer 转换成 LifecycleEventObserver,分发事件的时候调用了 mLifecycleObserver.onStateChanged() 方法,但是我们在使用的时候明明是 LifecycleObserver 或者 FullLifecycleObserver,主要是原理在 Lifecycling.lifecycleEventObserver(observer) 里面,本质上是一个工具类,把传递进来的 observer 转化成 LifecycleEventObserver,主要是通过适配器来转化的。

static LifecycleEventObserver lifecycleEventObserver(Object object) {
    // 是否为LifecycleEventObserver类型
    boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;
    // 是否为FullLifecycleObserver类型
    boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;
    // 1.这种情况发生在自定义Observer,上面两种都实现了
    if (isLifecycleEventObserver && isFullLifecycleObserver) {
        return new FullLifecycleObserverAdapter((FullLifecycleObserver) object,
                (LifecycleEventObserver) object);
    }
    // 2. FullLifecycleObserver 将object当做FullLifecycleObserver传递
    if (isFullLifecycleObserver) {
        return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, null);
    }
    // 3. LifecycleEventObserver 直接返回object本身
    if (isLifecycleEventObserver) {
        return (LifecycleEventObserver) object;
    }
    //······
}
  1. 判断 observer 是否为 LifecycleEventObserver && FullLifecycleObserver,如果条件都成立(一般发生在自定义的 Observer,即实现了两个接口),返回了一个FullLifecycleObserverAdapter,它实现了 LifecycleEventObserver 接口,复写了onStateChanged()方法,判断 Event 的类型,从而回调传递进来的 FullLifecycleObserver 相应的方法,如果还实现了 mLifecycleEventObserver 接口,则最后还会回调mLifecycleEventObserver.onStateChanged()方法。
// 实现LifecycleEventObserver接口
class FullLifecycleObserverAdapter implements LifecycleEventObserver {
    // mFullLifecycleObserver回调生命周期方法
    @Override
    public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
        switch (event) {
            case ON_CREATE:
                mFullLifecycleObserver.onCreate(source);
                break;
            case ON_START:
                mFullLifecycleObserver.onStart(source);
                break;
            case ON_RESUME:
                mFullLifecycleObserver.onResume(source);
                break;
            case ON_PAUSE:
                mFullLifecycleObserver.onPause(source);
                break;
            case ON_STOP:
                mFullLifecycleObserver.onStop(source);
                break;
            case ON_DESTROY:
                mFullLifecycleObserver.onDestroy(source);
                break;
        }
        // 回调mLifecycleEventObserver的onStateChanged()方法
        if (mLifecycleEventObserver != null) {
            mLifecycleEventObserver.onStateChanged(source, event);
        }
    }
}
  1. 如果仅仅是实现了 FullLifecycleObserver,同样是返回了一个FullLifecycleObserverAdapter,但是 lifecycleEventObserver 为 null,说明不再回调 onStateChanged(source, event) 方法,实际上通过 FullLifecycleObserverAdapter 包装实现转化过程,将 LifecycleObserver 转化为 LifecycleEventObserver。

  2. 如果是直接实现了 LifecycleEventObserver 的则直接返回,那么在生命周期事件分发的时候, Observer 就能直接分发到 onStateChanged() 这个方法里面。

static LifecycleEventObserver lifecycleEventObserver(Object object) {
    ·····
    final Class klass = object.getClass();
    // 获取Observer构造器类型,是否添加了注解编译器
    int type = getObserverConstructorType(klass);
    // 提供了两种策略
    if (type == GENERATED_CALLBACK) {
        //提供了两种策略
        List> 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);
        }
        // 返回CompositeGeneratedAdaptersObserver
        return new CompositeGeneratedAdaptersObserver(adapters);
    }
    // 返回ReflectiveGenericLifecycleObserver,内部实现依赖反射
    return new ReflectiveGenericLifecycleObserver(object);
}

上面的代码则是判断 LifecycleOberver,我们知道它只是一个空实现,但是为什么还要定义这个接口呢?这里仅仅是起到一个约束和规范的作用,方便在运行的时候判断 Observer 是那种类型。

public interface LifecycleObserver {

}

如果 Observer 是实现了 LifecycleOberver 这个接口的,它在运行的时候,分发事件的时候它提供了两种策略:

  1. 第一种是把 Observer 包装成一个 ReflectiveGenericLifecycleObserver,同样是实现了LifecycleEventObserver,在 onStateChanged() 调用了 invokeCallbacks() 方法通过反射的形式来调用自定义的 Observer 中相关方法。
// LifecycleObserver内部实现依赖反射
class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver {
    @Override
    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Event event) {
        //通过反射的形式来调用自定义的Observer中相关方法
        mInfo.invokeCallbacks(source, event, mWrapped);
    }
}
  1. 第二种如果在 gradle 文件中添加了 lifecycle_compiler 依赖,它实际上是编译器的意思,里面包含了一个注解处理器,在编译阶段就会为 Observers 生成相应适配的类。

比如上面 Lifecycle 实现方式的第一种:

public class MyLifecycleObserver implements LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void onStart(@NotNull LifecycleOwner owner) {

    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void onStop(@NotNull LifecycleOwner owner) {

    }
}

编译时会在 build.generated.source.kapt.debug 文件下自动生成MyLifecycleObserver_LifecycleAdapter.java 文件,在它的实现里面,就是根据事件的类型,回调到 MyLifecycleObserver 的 onStart() 和 onStop() 方法,这里为什么能直接回调呢?因为它在编译阶段生成的这个类,就能扫描到 MyLifecycleObserver 中的方法上标记的注解OnLifecycleEvent,然后拿到方法的名称,以及它的参数,生成下面的源码,就不用使用反射调用 MyLifecycleObserver 类中的方法了。

Android架构灵魂组件Lifecycle的生命周期机制详解_第4张图片

但是如何判断有没有引入 lifecycle-compiler 这个编译器的,通过 int type = getObserverConstructorType(klass) 判断构造器类型,跟踪来到 generatedConstructor() 中:

// 传入一个Class,实际上是就是上面定义的MyLifecycleObserver
private static Constructor generatedConstructor(Class klass) {
    try {
        //获取包名
        Package aPackage = klass.getPackage();
        //获取类名
        String name = klass.getCanonicalName();
        final String fullPackage = aPackage != null ? aPackage.getName() : "";
        // 获取adapterName拼接后的类名
        final String adapterName = getAdapterName(fullPackage.isEmpty() ? name :
                name.substring(fullPackage.length() + 1));

        final Class aClass =
                (Class) Class.forName(
                        fullPackage.isEmpty() ? adapterName : fullPackage + "." + adapterName);
        Constructor constructor =
                aClass.getDeclaredConstructor(klass);//反射加载这个类,
        if (!constructor.isAccessible()) {//如果没有异常,说明类存在
            constructor.setAccessible(true);
        }
        return constructor;
    } catch (ClassNotFoundException e) {
        return null;
    } catch (NoSuchMethodException e) {
        throw new RuntimeException(e);
    }
}

adapterName 的类名拼接,实际上是 MyLifecycleObserver 拼接上 _LifecycleAdapter,如下:

public static String getAdapterName(String className) {
    return className.replace(".", "_") + "_LifecycleAdapter";
}

如果类存在了,说明引入了 lifecycle-compiler 这个编译器,如果抛出异常就说明没有引入这个编译器。

这样它就能够区分,对于是直接实现 LifecycleObserver 的情况,是返回 CompositeGeneratedAdaptersObserver 还是返回 ReflectiveGenericLifecycleObserver,从而采用不同的策略来回调方法。

四、总结

Lifecycle 原理时序图如下:

Android架构灵魂组件Lifecycle的生命周期机制详解_第5张图片

  1. 监听过程就是 Activity/Fragment 继承 LifecycleOwner,并在子类 CommponentActivity 中创建 Lifecycle 的子类 LifecycleRegistry。复写 getLifecycle() 的方法中将子类 LifecycleRegistry 返回

  2. 在 onCreate() 中注入 ReportFragment,在生命周期回调后,通过 getLifecycle() 的方法得到 LifecycleRegistry 对象中的 handleLifecycleEvent(event) 方法给每个观察者派发生命周期事件

  3. addObserver() 中先初始化状态,然后计算出它应该到达的状态(目标状态),while()循环会让当前的观察者的状态从init状态前进到目标状态,再根据状态获取相应的事件,Observe 调用 dispatchEvent() 分发事件

  4. 宿主每个生命周期方法里面执行 handleLifecycleEvent(event),event.getTargetState() 根据当前的事件推导出每个观察者目标的生命周期状态,进行升级或者降级处理。然后遍历所有观察者,根据当前观察者的状态,计算出它对应的事件,分别进行 observer.dispatchEvent() 分发事件。

关于 Lifecycle 面试常问几个问题:

  1. Activity 里面是如何实现 Lifecycle 事件的分发的

:是通过添加透明 ReportFragment.

  1. 在 onResume 方法里面注册 Observer,是否能接受到完整的分发事件?

:能。

Lifecycle 几乎是 Jetpack 组件的核心,所有具有生命周期感知能力的组件都会用到 Lifecycle,包括 ViewModel和 Livedata。Lifecycle 实现了执行的逻辑和活动的分离,代码解耦并且增加了代码的额可读性。Lifecycle 在活动结束时自动移除监听,避免了生命周期的问题。

总的来说,观察宿主生命周期有三种写法,推荐第二种和第三种,第一种需要使用注解标记,要么是反射,要么是要添加注解处理器,生成适配的类。

Android 学习笔录

Android 性能优化篇:https://qr18.cn/FVlo89
Android Framework底层原理篇:https://qr18.cn/AQpN4J
Android 车载篇:https://qr18.cn/F05ZCM
Android 逆向安全学习笔记:https://qr18.cn/CQ5TcL
Android 音视频篇:https://qr18.cn/Ei3VPD
Jetpack全家桶篇(内含Compose):https://qr18.cn/A0gajp
OkHttp 源码解析笔记:https://qr18.cn/Cw0pBD
Kotlin 篇:https://qr18.cn/CdjtAF
Gradle 篇:https://qr18.cn/DzrmMB
Flutter 篇:https://qr18.cn/DIvKma
Android 八大知识体:https://qr18.cn/CyxarU
Android 核心笔记:https://qr21.cn/CaZQLo
Android 往年面试题锦:https://qr18.cn/CKV8OZ
2023年最新Android 面试题集:https://qr18.cn/CgxrRy
Android 车载开发岗位面试习题:https://qr18.cn/FTlyCJ
音视频面试题锦:https://qr18.cn/AcV6Ap

你可能感兴趣的:(Android,架构,Jetpack,compose,android,架构,移动开发,framework,安卓,android,jetpack)