Jetpack 相关控件(好懂版)系列之1: LifeCycle

300 阅读10分钟

简历里吹牛逼说我会用Jetpack 实现MVVM模式,其实根本就是一知半解。吹过的牛总是要还的,面试的现实和结果啪啪打脸。

image.png

洗心革面,在这个系列文章里从源码开始仔细的分析各个Jetpack 相关控件的使用方法和原理。如果你也和我一样在准备面试,就一起学习吧。从Lifecycle开始

(1)LifeCycle的简单介绍和作用

首先第一个问题,什么是LifeCycle? LifeCycle可以帮助构建生命周期感知型组件,这些组件可以根据 Activity 或 Fragment 的当前生命周期状态调整行为。

换句话说LifeCycle能够让我们自己定义的观察者类感知Activity 或 Fragment 的当前生命周期状态,然后根据当前生命周期状态做一些操作,这是是一个观察者(自己写)和被观察者(一般是Activity 或 Fragment)的关系。

Jetpack的剩余组件都是基于它实现的。

感知生命周期还有什么用呢?

假设我们有一个播放器类,它可能被用在多个Activity 或 Fragment 中,每次当Activity 或 Fragment需要被销毁的时候,就要进行停止播放,资源的释放,解注册,变量置空等等一系列操作。如果每次在Ondestory回调中都写这么多操作,是不是很麻烦?而且很可能忘记写。

这时候有LifeCycle,在LifeCycle框架下我们让播放器类作为观察者,Activity 或 Fragment作为被观察者,那么当执行到对应的生命周期时可以自动执行这些操作。

此外,有些时候为了纠正错误时机的异步任务,我们要设置Activity的活跃状态,是否处于激活状态,没有LifeCycle的情况下也要手动设置,而有了LifeCycle也可以自动管理。

那么可以总结一下:

LifeCycle是一个防止内存泄漏的大杀器

  • 无需在组件里生命周期方法里放置大量代码,即可实现对组件生命周期的监听的处理,再实现解耦的同时,让代码更有条理且精简易维护;
  • Lifecycle组件不会直接持有生命周期组件(Activity,Fragment等)的强引用,可以避免潜在的内存泄露问题。

(2) Lifecycle组件的简单使用和原理

这么说有点抽象,通过一个例子先来说明Lifecycle是怎么用的,然后基于这个例子说明其原理。

首先假设我们有一个工具类 Util 它需要根据Activity的生命周期回调进行一些操作。看代码


/**
 * 一个工具类,用来监听activity的生命周期
 */
public class Util implements DefaultLifecycleObserver {

    //活动创建
    @Override
    public void onCreate(@NonNull LifecycleOwner owner) {
        DefaultLifecycleObserver.super.onCreate(owner);
    }
    
    //活动resume
    @Override
    public void onResume(@NonNull LifecycleOwner owner) {
        DefaultLifecycleObserver.super.onResume(owner);
    }
    //活动销毁
    @Override
    public void onDestroy(@NonNull LifecycleOwner owner) {
        DefaultLifecycleObserver.super.onDestroy(owner);
    }
   //....其他回调
}

这里Util实现了一个DefaultLifecycleObserver接口,接口的回调方法可以接收到活动的全生命周期流程(相信你能明白)

那么如何让这个Util能够监听活动生命周期回调呢?

/**
 * 添加观察者
 */
getLifecycle().addObserver(new Util());

只需在MainActivity活动中执行这句代码就好了。

完成这一步,MainActivity所有的生命周期都会被回调到Util的各个生命周期方法之中。

非常简单和好用,那它实现的原理是什么呢?

首先我们实现这个功能,只不过是让工具类实现了一个接口,调用一个添加观察者方法,getLifecycle().addObserver(new Util());,就能监测到活动的生命周期了。

那么就从这两个地方出发。

首先看实现的接口: DefaultLifecycleObserver

public interface DefaultLifecycleObserver : LifecycleObserver {
    /**
     * Notifies that `ON_CREATE` event occurred.
     *
     *
     * This method will be called after the [LifecycleOwner]'s `onCreate`
     * method returns.
     *
     * @param owner the component, whose state was changed
     */
    public fun onCreate(owner: LifecycleOwner) {}

    /**
     * Notifies that `ON_START` event occurred.
     *
     *
     * This method will be called after the [LifecycleOwner]'s `onStart` method returns.
     *
     * @param owner the component, whose state was changed
     */
    public fun onStart(owner: LifecycleOwner) {}

    /**
     * Notifies that `ON_RESUME` event occurred.
     *
     *
     * This method will be called after the [LifecycleOwner]'s `onResume`
     * method returns.
     *
     * @param owner the component, whose state was changed
     */
    public fun onResume(owner: LifecycleOwner) {}

    /**
     * Notifies that `ON_PAUSE` event occurred.
     *
     *
     * This method will be called before the [LifecycleOwner]'s `onPause` method
     * is called.
     *
     * @param owner the component, whose state was changed
     */
    public fun onPause(owner: LifecycleOwner) {}

    /**
     * Notifies that `ON_STOP` event occurred.
     *
     *
     * This method will be called before the [LifecycleOwner]'s `onStop` method
     * is called.
     *
     * @param owner the component, whose state was changed
     */
    public fun onStop(owner: LifecycleOwner) {}

    /**
     * Notifies that `ON_DESTROY` event occurred.
     *
     *
     * This method will be called before the [LifecycleOwner]'s `onDestroy` method
     * is called.
     *
     * @param owner the component, whose state was changed
     */
    public fun onDestroy(owner: LifecycleOwner) {}
}

不用认真看了,啥也没有,就是一个继承自LifecycleObserver接口的接口,不过值得注意的是,它的每个回调都会传入一个LifecycleOwner对象,这个东西是个啥?

这时候就要去找我们添加观察的代码(getLifecycle().addObserver(new Util());)继续溯源了

首先查看getLifecycle()方法(此方法存在于Activity中):

@NonNull
@Override
public Lifecycle getLifecycle() {
    return mLifecycleRegistry;
}

注意亮点: 1.它被@Override注释,代表是一个重写的方法,应该是Activity实现了某个接口后自己实现的方法

那是哪一个接口哦😯?原来Activity是实现了这个接口:

public interface LifecycleOwner { 
@NonNull Lifecycle getLifecycle(); }

**找到了LifecycleOwner,原来观察者收到的就它,它也就是活动自己;接口其实也没啥,就是规定实现该接口的类要重写该方法返回一个Lifecycle实例,

2.这里Activity返回一个mLifecycleRegistry实例对象,不难猜出,mLifecycleRegistry就是一个Lifecycle类或子类的实例,请看

private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

哦原来它是LifecycleRegistry类的实例,这个类的源码有点子复杂哦,我们先不细看,你只要看我们传入了this,也就是Activity进去了。

然后,我们不是调用了getLifecycle()(实际是mLifecycleRegistry)的addObserver()方法吗?先看addObserver是咋个回事.

在这之前,总结一下目前的情况啊

1.Activity 实现了一个 LifecycleOwner接口,并重写了getLifecycle()方法

2.getLifecycle()方法中返回一个mLifecycleRegistry实例对象,接着我们调用该实例对象的addObserver()方法,将观察者添加到此实例对象

好了,mLifecycleRegistry的类型是LifecycleRegistry类,LifecycleRegistry类Lifecycle类的具体实现类。先进去看一下addObserver()方法

override fun addObserver(observer: LifecycleObserver) {
    enforceMainThreadIfNeeded("addObserver")
    val initialState = if (state == State.DESTROYED) State.DESTROYED else State.INITIALIZED
    val statefulObserver = ObserverWithState(observer, initialState)
    val previous = observerMap.putIfAbsent(observer, statefulObserver)
    if (previous != null) {
        return
    }
    val lifecycleOwner = lifecycleOwner.get()
        ?: // it is null we should be destroyed. Fallback quickly
        return
    val isReentrance = addingObserverCounter != 0 || handlingEvent
    var targetState = calculateTargetState(observer)
    addingObserverCounter++
    while (statefulObserver.state < targetState && observerMap.contains(observer)
    ) {
        pushParentState(statefulObserver.state)
        val event = Event.upFrom(statefulObserver.state)
            ?: throw IllegalStateException("no event up from ${statefulObserver.state}")
        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()
    }
    addingObserverCounter--
}

代码还是比较长哦,但不要慌,小伙子,我教你慢慢看呗,其实我们先看添加观察者,添加到什么地方去了不就行了,后面的其实不用管

val initialState = if (state == State.DESTROYED) State.DESTROYED else State.INITIALIZED
val statefulObserver = ObserverWithState(observer, initialState)
val previous = observerMap.putIfAbsent(observer, statefulObserver)

真正将传入的observer: LifecycleObserver做保存的就是这几行代码,其实不难理解,我们不是做生命周期回调吗,那每个观察者目前回调那个方法总得记录一下吧? 于是就有了这一句:

val initialState = if (state == State.DESTROYED) State.DESTROYED else State.INITIALIZED

给观察者分配一个初始状态:如果当前的Lifecycle的状态是毁灭,我也毁灭,不是的话我这个观察者目前处于初始化状态。

接下来:

将状态和观察者包装一下

val statefulObserver = ObserverWithState(observer, initialState)

传入一个Map缓存,也没啥复杂的。

val previous = observerMap.putIfAbsent(observer, statefulObserver)

总结,mLifecycleRegistry的addObserver方法干啥了,1.就是分配一个初始状态给观察者(也就是工具类实现了观察者接口,这个工具类就变成观察者了),2.然后用一个类实例把状态和观察者包装一下,放在一起去,方便一起管理。3.接着把包装好的观察者及其状态保存到一个Map中

这里把观察者放到Map里也不难理解吧,下一步如果mLifecycleRegistry收到了生命周期事件(比如活动创建了,它就在Map中取出对应的观察者,调用观察者的Oncreate()回调啊。这不就实现了观察者观察活动状态吗?

好的,现在找下一步,Activity是如何通知mLifecycleRegistry生命周期变化事件的

在Activity的onCreate中有一句颇为神秘的代码:

ReportFragment.injectIfNeededIn(this);

点进去看你就看见

public static void injectIfNeededIn(Activity activity) {
    if (Build.VERSION.SDK_INT >= 29) {
        // On API 29+, we can register for the correct Lifecycle callbacks directly
        //直接向 android.app.Activity 注册生命周期回调
        activity.registerActivityLifecycleCallbacks(
                new LifecycleCallbacks());
    }
    // 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
    //向 activity 添加一个不可见的 fragment
    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();
    }
}

这是一个分SDK版本的注册代码,如果Build.VERSION.SDK_INT >= 29 则通过

activity.registerActivityLifecycleCallbacks( new LifecycleCallbacks()); }

来注册活动生命周期的回调来监测生命周期变化,这个地方是Activity提供的注册监听api,你别管如何实现的,你就知道只要注册这个回调,你就能获取Activity的生命周期变化就得了

但话说回来其实我知道它是怎么个原理,安卓里AMS负责应用进程的启动,负责ActivityThread 的main 方法的执行和初始化,负责任务栈活动栈的管理,前后台切换等等工作。

而具体的生命周期调度,实际是由ActivityThread 负责管理 Activity 的整个生命周期流程,例如创建、启动、暂停、销毁等操作的调度。因此,不难猜测这里还是ActivityThreadActivity的生命周期回调给LifecycleCallbacks好吧

总之,反之我们的生命周期回调到了LifecycleCallbacks中,去看一下它干了啥

static class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
    @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 onActivityPreDestroyed(@NonNull Activity activity) {
        dispatch(activity, Lifecycle.Event.ON_DESTROY);
    }

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

好吧,你看不过就在各个生命周期回调里调用

dispatch(activity, Lifecycle.Event.ON_DESTROY);

方法,继续看dispatch方法干啥了

@SuppressWarnings("deprecation")
static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
   //LifecycleRegistryOwner 已被废弃,主要看 LifecycleOwner
   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);
       }
   }
}

注意看这一段

 if (activity instanceof LifecycleOwner) {
        Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
        if (lifecycle instanceof LifecycleRegistry) {
            ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
        }
    }

说来说去,还是通过getLifecycle()拿到了mlifecycleRegistry实例,调用其handleLifecycleEvent(event); 把对应的生命周期事件传入去分发呗。

别忘了mlifecycleRegistry可是通过一个map保存过我们的观察者,不是吗? 你记得吧,那么在获取到对应的生命周期事件之后,不就能根据生命周期去回调观察者的方法吗?

看看是如何分发的

public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
   State next = getStateAfter(event);
   moveToState(next);
}

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

总体逻辑,先根据周期事件->更新状态( State next = getStateAfter(event); moveToState(next);),更新状态之后,再同步给注册的观察者( sync();方法)

在sync()中,其实做了很多操作,比如当前观察者的状态和目前更新的状态是否一致,不一致才让观察者接收新的周期事件等等,但总之,它回循环所有观察者 调用:

observer.dispatchEvent(lifecycleOwner, event);

将生命周期事件回调给观察者

(3) 总结一下

总结一下:

Lifecycle组件中有三个重要的组件:

1. LifecycleOwner、2.LifecycleRegistry/Lifecycle和3.LifecycleObserver。

它们分别扮演着生产者,管理者和消费者的角色。整个组件就是围绕着三个角色实现对生命周期的控制和调度的。

LifecycleOwner(活动)负责发出生命周期

LifecycleRegistry(存储LifecycleOwner和观察者,接受LifecycleOwner传递的生命周期事件,并遍历观察者回调生命周期事件)负责存储和调度

LifecycleObserver通过和LifecycleRegistry绑定实现对生命周期的监听和消费。