Jetpack-Lifecycle源码分析

Lifecycle简介

Lifecycle类持有相关组件(Activity或者Fragment)生命周期状态的信息,通过Event和State来体现关联的生命周期的状态,允许业务组件观察此生命周期状态,从而达到业务组件分别处理生命周期相关的业务。
Lifecyle是LiveData的基石,充分理解Lifecycle实现机制对于后续研究Jetpack其他组件很有必要。

特点

感知Activity或者Fragment的生命周期,利用这点我们更好的组织业务组件,更轻量级的代码。

职责

Lifecycle UML关系图

LifecycleObserver
实现LifecycleObserver接口的类,使用注解OnLifecycleEvent修饰方法。LifecycleOwner类addObserver方法注册后,LifecycleObserver便可以观察到LifecycleOwner的生命周期变化。
LifecycleObserver派生接口有GenericLifecycleObserver和DefaultLifecycleObserver。由于DefaultLifecycleObserver使用接口default实现接口,所以只能在java 8环境下使用。

LifecycleOwner
实现LifecycleOwner接口的类持有Lifecycle对象,会把自身的生命周期变化同步给Lifecycle对象,Lifecycle对象通知已注册观察者LifecycleObserver,从而观察者触发对应的事件。

LifecycleRegistryOwner
继承LifecycleOwner,alpha版本引入,目前已过时,分析源码时,可以掉过。

Lifecycle
实现Lifecycle接口的类可以注册和注销LifecycleObserver对象,同时获取当前State。

LifecycleRegistry
LifecycleRegistry是一个成熟的 Lifecycle 实现类,是LifecycleObserver和LifecycleOwner连接的桥梁。实现注册和注销LifecycleObserver对象,同时可以接受LifecycleOwner生命周期变化,通知已注册的LifecycleObserver对象对象。
Activity和Fragment中都是使用LifecycleRegistry,如果我们需要自定义LifecycleOwner 并实现接口需要返回一个Lifecycle实例,Google推荐直接使用LifecycleRegistry实例。

源码分析

所有源码分析都是基于lifecyce 1.1.1版本,1.1.1版本中存留一部分对之前alpha版本的兼容支持,阅读源码时,一般会忽略,特殊情况下会添加说明。

基础知识

在解释Lifecycle如何实现监听Activity的生命周期变化之前需要了解一些基础知识。

区分android.app.和android.support.

android.app.* 属于android bundle sdk,apk中不包含sdk源码生成的class,而是依赖Android设备出厂是内置sdk实现;

android.support.*属于Google Android Support Library,在编译和打包时与自研或者第三方sdk没有区别,会把源码生成的class生成到apk中;

Activity与Fragment

常用Activity继承关系如下:
AppCompatActivity extends FragmentActivity extends SupportAcitivity extends Activity。

AppCompatActivity和FragmentActivity的FragmentManager实现是android.support.v4.app.FragmentManager,只支持add, remove, replace等Support Library库中的Fragment操作;

SupportActivity和Activity的FragmentManager实现是android.app.FragmentManager;只支持add, remove, replace等android.app.Fragment操作;

Headless Fragment

无UI Fragment,生命周期与FragmentManager关联,FragmentManager生命周期与Activity关联,所以Headless Fragment生命周期与Activity一致。

Retained Fragment

无UI Fragment,添加setRetainInstance(true),数据不会因为Activity configurationChanged丢失。

Google工作人员表示开发Lifecycle并没有针对android.app.* Activity和Fragment,近期也未打算支持android.app.*。具体参见官方解释。这里推荐大家更多的使用support包,不同版本platform中Activity和Fragment还存在大量support包中已修复的bug。

如何监听生命周期事件

android.support.v4.Fragment

android.support.v4.Fragment实现了LifecycleOwner接口,意味着Fragment对象持有Lifecycle对象,可以通过getLifecycle()方法获取Lifecycle对象完成注册和注销LifecycleObserver对象。

public class Fragment implements LifecycleOwner {
    LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    public Lifecycle getLifecycle() {
        return this.mLifecycleRegistry;
    }
    ...
}

源码中Lifecycle对象的具体实现是LifecycleRegistry。
Fragment在生命周期相关方法中使用LifecycleRegistry完成生命周期同步给LifecycleObserver对象。

public class Fragment implements LifecycleOwner {
    void performResume() {
        if (this.mChildFragmentManager != null) {
            this.mChildFragmentManager.dispatchResume();
            this.mChildFragmentManager.execPendingActions();
        }
        this.mLifecycleRegistry.handleLifecycleEvent(Event.ON_RESUME);
    }

    void performPause() {
        this.mLifecycleRegistry.handleLifecycleEvent(Event.ON_PAUSE);
        if (this.mChildFragmentManager != null) {
            this.mChildFragmentManager.dispatchPause();
        }
    }
}

同时发现Fragment中performCreate()、performStart()、performResume()会先调用自身的onXXX()方法,然后再调用LifecycleRegistry的handleLifecycleEvent()方法;而在performPause()、performStop()、performDestroy()中会先LifecycleRegistry的handleLifecycleEvent()方法 ,然后调用自身的onXXX()方法。

以上基本解释清楚Lifecycle如何实现监听Fragment(extends android.support.v4.Fragment)的生命周期变化。

android.support.v4.SupportAcitivity

我们常用Support Library下的Activity(AppCompatActivity, FragmentActivity)继承 android.support.v4.SupportAcitivity,我们分析清楚SupportActivity,便了解Lifecycle如何实现监听Support Library下的Activity生命周期。

public class SupportActivity extends Activity implements LifecycleOwner, XXX {
    private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ReportFragment.injectIfNeededIn(this);
    }
    public Lifecycle getLifecycle() {
        return this.mLifecycleRegistry;
    }
    @CallSuper
    protected void onSaveInstanceState(Bundle outState) {
        this.mLifecycleRegistry.markState(State.CREATED);
        super.onSaveInstanceState(outState);
    }
}

ReportFragment源码:

import android.app.Fragment;
public class ReportFragment extends Fragment {
    private static final String REPORT_FRAGMENT_TAG = "android.arch.lifecycle"
            + ".LifecycleDispatcher.report_fragment_tag";

    public static void injectIfNeededIn(Activity activity) {
        android.app.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 onStart() {
        super.onStart();
        dispatch(Lifecycle.Event.ON_START);
    }
    ...
    @Override
    public void onDestroy() {
        super.onDestroy();
        dispatch(Lifecycle.Event.ON_DESTROY);
    }
    private void dispatch(Lifecycle.Event event) {
        Activity activity = getActivity();
        if (activity instanceof LifecycleOwner) {
            Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
            if (lifecycle instanceof LifecycleRegistry) {
                ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
            }
        }
    }
}

ReportFragment继承android.app.Fragment,虽然SupportActivity在Support Library中,继承android.app.Activity,可以切只能使用android.app.FragmentManager操作android.app.Fragment。
AppCompatActivity,FragmentActivity和SupportActivity通过ReportFragment使用Headless Fragment机制完成把生命周期同步给LifecyceObserver。

以上基本分析清楚LifecyceObserver如何监听Support Library下Activity和Fragment的生命周期。如何支持监听android.app.Activity和android.app.Fragment的生命周期,后面详细赘述。

应用前后台变化

在我们开发工作中,应用前后台变化时,需要完成某些业务处理。同样Lifecycle也支持LifecycleObserver监听应用前后台变化。

ProcessLifecycleOwner.get().lifecycle.addObserver(this)

应用前后台变化,与应用每个Activity的生命周期变化相关,通过前面的分析,我们可以监听到Support Library所有Activity的生命周期变化,但是没有监听到android.app.Activity的生命周期。接下来,再来分析Lifecycle如何实现监听应用前后台变化。

extensions包下存在ProcessLifecycleOwnerInitializer类:

public class ProcessLifecycleOwnerInitializer extends ContentProvider {
    @Override
    public boolean onCreate() {
        LifecycleDispatcher.init(getContext());
        ProcessLifecycleOwner.init(getContext());
        return true;
    }
    ...
}

ProcessLifecycleOwnerInitializer利用ConentProvider生命周期完成LifecycleDispatcher和ProcessLifecycleOwner初始化。

LivecycleDispatcher源码:

class LifecycleDispatcher {
    private static final String REPORT_FRAGMENT_TAG = "android.arch.lifecycle"
            + ".LifecycleDispatcher.report_fragment_tag";
    private static AtomicBoolean sInitialized = new AtomicBoolean(false);
    static void init(Context context) {
        if (sInitialized.getAndSet(true)) {
            return;
        }
        ((Application) context.getApplicationContext())
                .registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
    }
    static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {
        DispatcherActivityCallback() { }
        @Override
        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            ReportFragment.injectIfNeededIn(activity);
        }
    }
}

去除alpha版本兼容和过时API LifecycleRegistryOwner相关代码后,代码非常简洁。如果Activity内不存在ReportFragment,动态添加一个Headless Fragment ReportFragment。之前分析过Support Library 中的Activity已经在创建时自行的添加ReportFragment,所以这里主要是为android.app.Activity添加ReportFragment。

ProcessLifecycleOwner源码:

public class ProcessLifecycleOwner implements LifecycleOwner {
    private ActivityInitializationListener mInitializationListener =
            new ActivityInitializationListener() {
                @Override
                public void onCreate() {
                }
                @Override
                public void onStart() {
                    activityStarted();
                }
                @Override
                public void onResume() {
                    activityResumed();
                }
            };
    void attach(Context context) {
        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
        Application app = (Application) context.getApplicationContext();
        app.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                ReportFragment.get(activity).setProcessListener(mInitializationListener);
            }
            @Override
            public void onActivityPaused(Activity activity) {
                activityPaused();
            }
            @Override
            public void onActivityStopped(Activity activity) {
                activityStopped();
            }
        });
    }
}

所有Activity都已经添加了ReportFragment后,ProcessLifecycleOwner通过ReportFragment监听Activity的onStart,OnResume,通过ActivityLifecycleCallback监听onPause,onStop。

疑问:为什么使用ActivityLifecycleCallback只监听onPause,onStop,onStart,OnResume交给ReportFragment实现监听?

如何通知LifecycleObserver生命周期变化

通过如何监听生命周期变化,我们把生命周期变化收集在LifecycleRegistry的handleLifecycleEvent统一处理。
在深入handleLifecycleEvent实现之前,我们需要搞定State和Event的设计和实现。

我们需要弄清楚两个问题:

  1. 发生Event后更新State规则是什么?
  2. 更新State后针对每个的LifecyceObserver分发Event的规则是什么?


    Event State关系图

上图是Lifecycle官方State和Event关系图,State自左向右依次递增,Event分为向左Event和向右Event两类。
向左Event包含ON_CREATE,ON_START,ON_RESUME;
向右Event包含ON_PAUSE,ON_STOP,ON_DESTROY;

从上图可以直接得到发生Event后更新State规则如下:

发生Event 发生Event后State
ON_CREATE,ON_STOP CREATED
ON_START,ON_PAUSE STARTED
ON_RESUME RESUMED
ON_DESTROY DESTROYED

在介绍更新State后针对每个的LifecyceObserver分发Event的规则是什么前,我们需要了解LifecycleRegistry如何持有LifecycleObser类。

/**
    * Custom list that keeps observers and can handle removals / additions during traversal.
    *
    * Invariant: at any moment of time for observer1 & observer2:
    * if addition_order(observer1) < addition_order(observer2), then
    * state(observer1) >= state(observer2),
    */
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
        new FastSafeIterableMap<>();
        
public void addObserver(@NonNull LifecycleObserver observer) {
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
    ...
}

在addObserver时,把LifecycleObserver和State包装成ObserverWithState,添加到mObserverMap中。
回去看Event State关系图,当Event发生后,通过发生Event后更新State规则获得最新state,根据最新State与mObserverMap中的每个state对比,针对对应的LifecycleObserver决定分发哪些Event。

下面来分析下核心代码,代码中只保留核心部分,后面会针对复杂场景详述细节,具体见注释。

/*
* mObserverMap双向链表规则:无论何时,先加入的observer的state要大于后加入的observer的state,决定sync实现
*/
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
    new FastSafeIterableMap<>();
    
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    //根据发生Event后更新State规则获得最新state
    State next = getStateAfter(event);
    moveToState(next);
}

private void moveToState(State next) {
    //更新最新state
    mState = next;
    sync();
}

//分发给LifecycleObserver
private void sync() {
    // 根据mObserverMap双向链表规则eldest的state最大
    // 如果最新state比eldest的state小,需要从eldest反向遍历mObserverMap中的LifecycleObserver分发同步Event
    // 具体细节见backwardPass注释
    if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
        backwardPass(lifecycleOwner);
    }

    Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
    // 根据mObserverMap双向链表规则newest的state最小
    // 如果最新state比newest的state大,需要从newest正向遍历mObserverMap中的LifecycleObserver分发同步Event
    // 具体细节见backwardPass注释
    if (newest != null && mState.compareTo(newest.getValue().mState) > 0) {
        forwardPass(lifecycleOwner);
}

private void backwardPass(LifecycleOwner lifecycleOwner) {
    //获得反向遍历Iterator
    Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
            mObserverMap.descendingIterator();

    while (descendingIterator.hasNext()) {
        //反向获得ObserverWithState
        Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
        ObserverWithState observer = entry.getValue();
        //不断对比ObserverWithState的state和最新state,直到相等
        while (observer.mState.compareTo(mState) > 0) {
            //根据ObserverWithState的state获得反向Event,
            Event event = downEvent(observer.mState);
            //分发event,同时observer内部state减小
            observer.dispatchEvent(lifecycleOwner, event);
        }
    }
}

private void forwardPass(LifecycleOwner lifecycleOwner) {
    //获得正向遍历Iterator
    Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
            mObserverMap.iteratorWithAdditions();

    while (ascendingIterator.hasNext()) {
        // 正向获得ObserverWithState
        Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
        ObserverWithState observer = entry.getValue();
        //不断对比ObserverWithState的state和最新state,直到相等
        while (observer.mState.compareTo(mState) < 0) {
            //根据ObserverWithState的state获得正向Event,
            observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
        }
    }
}

static class ObserverWithState {
    State mState;
    GenericLifecycleObserver mLifecycleObserver;

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

    void dispatchEvent(LifecycleOwner owner, Event event) {
        //根据分发event获得最新newState,
        State newState = getStateAfter(event);
        mState = min(mState, newState);
        //分发event
        mLifecycleObserver.onStateChanged(owner, event);
        //更新为最新state
        mState = newState;
    }
}

简单罗列下核心点:

  1. mObserverMap双向链表规则:无论何时,先加入的observer的state要大于后加入的observer的state,决定sync实现;
  2. forwardPass,根据最新state和ObserverWithState内部state对比,分发正向Event,即ON_CREATE,ON_START,ON_RESUME;
  3. backwardPass,根据最新state和ObserverWithState内部state对比,分发反向Event,即ON_PAUSE,ON_STOP,ON_DESTROY;
  4. 分发Event抽象的定义是GenericLifecycleObserver,我们后面详细分析。

相信通过上面的核心点介绍,大家已经了解更新State后针对每个的LifecyceObserver分发Event的规则;

LifecycleRegistry 本来要做的事其实是很简单的,但由于他需要执行客户的代码不在Lifecycle的控制之下,引入了很多额外的复杂处理。列举几个LifecycleRegistry处理的复杂场景:

  1. 同步Event过程中,添加或者移除LifecycleObserver;
  2. 添加新LifecycleObserver过程中,收到同步Event请求;
  3. 同步Event 或者 添加新的LifecycleObserver过程中,收到新的同步Event请求;
    为了处理和兼容以上场景可能出现的问题,LifecyRegsitry中引入以下变量来协调处理。
//!=-表示正在添加observer
private int mAddingObserverCounter = 0;
//true表示正在同步Event
private boolean mHandlingEvent = false;
//true表示正在同步同步或者添加observer过程中,收到新的同步Event请求;
private boolean mNewEventOccurred = false;
// we have to keep it for cases:
// void onStart() {
//     mRegistry.removeObserver(this);
//     mRegistry.add(newObserver);
// }
// 假定现在我们要从 CREATED 转到 STARTED 状态(也就是说,mState 现在是 STARTED)。
// 这种情况下,只有将新的 observer 设置为 CREATED 状态,它的 onStart 才会被调用
// 为了得到这个 CREATED,在这里才引入了 mParentStates。
private ArrayList<State> mParentStates = new ArrayList<>();

总结

整体分析Lifecycle时,其中应用到很多比较基础的知识,利用这些基础知识巧妙的解决生命周期监听问题。LifecycleRegistry中思路比较简单,实现细节考虑到复杂场景处理还是有些复杂的,阅读分析源码可以先抓重点问题理解,再针对复杂场景逐一分析。
深入了解Lifecycle后,会对后续我们灵活使用JetPack和分析具体问题相当收益。

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

推荐阅读更多精彩内容