Jetpack之Lifecycle源码

Android Jetpack 组件是库的集合,这些库是为协同工作而构建的,不过也可以单独采用,同时利用 Kotlin语言功能帮助您提高工作效率。可全部使用,也可混合搭配!

JetPack组件.png

1.什么是 Lifecycle?:它是可以感知 ActivityFragment 的生命周期,并将变化通知到已注册的观察者。让代码符合生命周期规范,有效的避免了内存泄漏等问题。

2.基本使用:被动的通知 View层生命周期变化让逻辑层拥有 LifecycleOwner对象,因为view层实现了 LifecycleOwner接口,所以可以在view层初始化的时候,直接赋值,有了 LifecycleOwner对象,就可以通过 getLifecycle方法获取到 Lifecycle对象了(附图片)。

image.png

  1. Lifecycle有4个比较重要的类: LifecycleOwnerLifecycleObserverLifecycleLifecycleRegistry

3.1 LifecycleOwner,它是一个接口,我们现在用的 Androidx包下的 AppcompatActivtyFragment都默认实现了 LifecycleOwner这个接口,这个接口提供了 getLifecycle() 方法来获取其 Lifecycle 对象。
也就是上面说的直接在 Activity添加 addObserver(new CustomObserver())就能感知 Activity生命周期了。

可以看到LifecycleOwner源码.png

3.2 LifecycleObserver,它是一个空的接口,这个接口只是来标志这个是对Lifecycle的观察者,内部没有任何方法,全部都依赖于OnLifecycleEvent注解

四个类之间的关系 .png

3.3 Lifecycle,它是一个抽象的类,定义了2个枚举类EventStateaddObserverremoveObserver方法。

image.png

3.4 LifecycleRegistry:它是 Lifecycle 的唯一实现类。主要用来注册观察者( LifecycleObserver),以及分发宿主状态给它们(可以处理多个观察者)

上面简单看了下四个类的源码。真正的源码如下所示
在看源码之前,,我们可能产生几个疑问

  • Lifecycle是怎样感知生命周期的?
  • Lifecycle是如何处理生命周期的?
  • LifecycleObserver的方法是怎么回调的呢?
  • 为什么LifecycleObserver可以感知到Activity的生命周期?

源码解析(以LifeCycleActivity.class为例):

image.png

上图中1标注的我们拆分成2步:getLifecycle()addObserver()
①先看getLifecycle():它是ComponentActivity里面的
image.png

mLifecycleRegistryLifecycleRegistry 对象,LifecycleRegistryLifeCycle 的子类;

②addObserver()

image.png

上面代码可看出,addObserver()干了以下几件事:
1、可以添加多个观察者,这时候需要维护他们的状态,每次添加新的观察者的初始状态是INITIALIZED
2、然后把LifecycleObserver包装成ObserverWithState
3、把Observer添加到map集合中。
观察者已经添加完成了,那么如何将生命周期的变化通知观察者呢?
再会到ComponentActivity中,仔细看下ComponentActivityonCreate()方法有一个
ReportFragment.injectIfNeededIn(this);
它初始化了一个ReportFragment,仔细看下ReportFragment源码可知,它是向Activity添加了一个没有页面的Fragment,并且ReportFragment中的各个生命周期都调用了dispatch(Lifecycle.Event event) 方法,
它里面的参数就是传递了不同的Event值,再仔细看dispatch里面干了2件事:
(1)如果Activity实现了LifecycleRegistryOwner接口的话,就调用LifecycleRegistryOwnerhandleLifecycleEvent的方法;
(2)如果Activity实现了LifecycleOwner接口的话,就调用LifecycleRegistryhandleLifecycleEvent的方法;
经过我们上面的介绍,Activity是实现了LifecycleOwner的接口,所以会执行LifecycleRegistryhandleLifecycleEvent的方法。

看到这里我们可以回答第4中的前2个问题了。

接下来看下handleLifecycleEvent方法

 public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    State next = getStateAfter(event);
    moveToState(next);
}
1.首先根据需要分发的事件,获取宿主当前处于什么状态

假设分发的是 ON_START 事件,那么根据 getStateAfter() 方法我们可以知道,宿主当前是处于STARTED 状态。

 static State getStateAfter(Event event) {
    switch (event) {
        case ON_CREATE:
        case ON_STOP:
            return CREATED;
        case ON_START:
        case ON_PAUSE:
            return STARTED;
        case ON_RESUME:
            return RESUMED;
        case ON_DESTROY:
            return DESTROYED;
        case ON_ANY:
            break;
    }
2.根据第一步获取的宿主状态设置当前的状态并通知观察者
private void moveToState(State next) {
    if (mState == next) {
        return;
    }
    //设置当前状态
    mState = next;

    ...

    //通知观察者
    sync();
}

下面来看一下 sync方法:

 private void sync() {

    while (!isSynced()) {

    //如果宿主当前的状态 小于 mObserverMap 集合中最先添加的那个观察者的状态
    //则说明宿主可能发生了状态回退,比如当前是 RESUMED 状态,执行了onPause 则回退到STARTED 状态
    //此时调用 backwardPass 给集合中的每个一观察者分发一个 on_pause 事件,并同步它的状态。
    if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
        backwardPass(lifecycleOwner);
    }

    //如果宿主当前状态 大于 mObserverMap 集合中最先添加的那个观察者的状态
    //则说明宿主可能发生了状态前进,比如当前是 STARTED 状态,执行了onResume 则前进到RESUMED 状态
    //此时调用 forwardPass 给集合中的每个一观察者分发一个 on_resume 事件,并同步它的状态。
    Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
    if (!mNewEventOccurred && newest != null
            && mState.compareTo(newest.getValue().mState) > 0) {
        forwardPass(lifecycleOwner);
    }
}
mNewEventOccurred = false;

}

ObserverWithState源码分析
ObserverWithStateLifecycleRegistry中持有观察者及其状态的内部类。

static class ObserverWithState {
     State mState;
     LifecycleEventObserver mLifecycleObserver;

     //把传入的 LifecycleObserver 适配成 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;
}

至此LifeCycle源码讲解完成,希望能大家有帮助,谢谢

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容