Lifecycle源碼解析

Lifecycle-Aware是Google官方的生命周期感知組件。同時(shí)幼驶,在Google推出的Android Jetpack組件中床绪,也將Lifecycle-Aware放在了Architecture類別之中婆廊。我們可以利用 android.arch.lifecycle 包提供的類來控制數(shù)據(jù)、監(jiān)聽器等的 lifecycle溺森。同時(shí)慕爬,LiveData和ViewModel的lifecycle也依賴于Lifecycle框架,所以我們有必要去了解一下Lifecycle儿惫。

image

一澡罚、Lifecycle組件初始化

/app/build/intermediates/manifests/full/debug/AndroidManifest.xml,是我們應(yīng)用在構(gòu)建完成之后完整生成的AndroidManifest.xml文件肾请。其中留搔,我們可以找到Lifecycle-Aware組件在AndroidManifest的定義。

    <provider
        android:name="android.arch.lifecycle.ProcessLifecycleOwnerInitializer"
        android:authorities="com.boohee.one.lifecycle-trojan"
        android:exported="false"
        android:multiprocess="true" />

ProcessLifecycleOwnerInitializer是ContentProvider的子類铛铁,利用其onCreate()生命周期方法隔显,處理Lifecycle組件初始化。因此饵逐,這是一種隱式初始化的方式括眠。

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

二、Lifecycle生命周期事件感知

繼續(xù)關(guān)注ProcessLifecycleOwnerInitializer的onCreate()方法倍权,其調(diào)用了LifecycleDispatcher的init()方法進(jìn)行相應(yīng)初始化掷豺。

    static void init(Context context) {
        if (sInitialized.getAndSet(true)) {
            return;
        }
        ((Application) context.getApplicationContext())
                .registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
    }

    @SuppressWarnings("WeakerAccess")
    @VisibleForTesting
    static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {
        private final FragmentCallback mFragmentCallback;

        DispatcherActivityCallback() {
            mFragmentCallback = new FragmentCallback();
        }

        @Override
        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            if (activity instanceof FragmentActivity) {
                ((FragmentActivity) activity).getSupportFragmentManager()
                        .registerFragmentLifecycleCallbacks(mFragmentCallback, true);
            }
            ReportFragment.injectIfNeededIn(activity);
        }

        @Override
        public void onActivityStopped(Activity activity) {
            if (activity instanceof FragmentActivity) {
                markState((FragmentActivity) activity, CREATED);
            }
        }

        @Override
        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
            if (activity instanceof FragmentActivity) {
                markState((FragmentActivity) activity, CREATED);
            }
        }
    }

init()方法其實(shí)就是在Application中注冊(cè)了一個(gè)ActivityLifecycleCallbacks監(jiān)聽(即DispatcherActivityCallback)捞烟,用來監(jiān)聽每個(gè)Activity的生命周期變化。
我們?cè)倏聪翫ispatcherActivityCallback的onActivityCreated()回調(diào)方法当船,如果Activity是FragmentActivity题画,則注冊(cè)一個(gè)FragmentLifecycleCallbacks(即FragmentCallback)用來監(jiān)聽Activity中Fragment的生命周期。

    static class FragmentCallback extends FragmentManager.FragmentLifecycleCallbacks {

        @Override
        public void onFragmentCreated(FragmentManager fm, Fragment f, Bundle savedInstanceState) {
            dispatchIfLifecycleOwner(f, ON_CREATE);

            if (!(f instanceof LifecycleRegistryOwner)) {
                return;
            }

            if (f.getChildFragmentManager().findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
                f.getChildFragmentManager().beginTransaction().add(new DestructionReportFragment(),
                        REPORT_FRAGMENT_TAG).commit();
            }
        }

        @Override
        public void onFragmentStarted(FragmentManager fm, Fragment f) {
            dispatchIfLifecycleOwner(f, ON_START);
        }

        @Override
        public void onFragmentResumed(FragmentManager fm, Fragment f) {
            dispatchIfLifecycleOwner(f, ON_RESUME);
        }
    }

我們看到FragmentCallback的onFragmentCreated()回調(diào)方法中德频,當(dāng)Fragment如果實(shí)現(xiàn)了LifecycleRegistryOwner苍息,就會(huì)為其添加一個(gè)DestructionReportFragment,用來監(jiān)聽Fragment的生命周期壹置。
之后竞思,會(huì)在Activity中添加一個(gè)ReportFragment,用來監(jiān)聽Activity生命周期钞护。

    // ReportFragment
    @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;
    }

    private void dispatch(Lifecycle.Event event) {
        Activity activity = getActivity();
        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);
            }
        }
    }

如此盖喷,利用一個(gè)附著在Activity上無UI的Fragment,通過相應(yīng)的生命周期回調(diào)方法患亿,實(shí)質(zhì)上是對(duì)Activity生命周期的監(jiān)聽传蹈。
至此,我們知道了Lifecycle組件通過ActivityLifecycleCallbacks步藕、FragmentLifecycleCallbacks及 無UI的Fragment來感知Activity/Fragment的生命周期變化并產(chǎn)生相應(yīng)的事件。

三挑格、Lifecycle生命周期事件分發(fā)

在上面的分析中咙冗,我們只是重點(diǎn)關(guān)注了Lifecycle如何感知生命周期,也就是如何監(jiān)聽Activity/Fragment的生命周期漂彤。在相應(yīng)的回調(diào)方法當(dāng)中雾消,其實(shí)都包含了很多生命周期事件分發(fā)相關(guān)的邏輯。通過相關(guān)的源碼分析挫望,我們可以發(fā)現(xiàn)最終都會(huì)調(diào)用到Activity/Fragment的getLifecycle()方法獲取Lifecycle對(duì)象立润,之后再調(diào)用Lifecycle對(duì)象的handleLifecycleEvent()方法進(jìn)行事件分發(fā)。26.1.0及更高版本Support支持庫(kù)中的Activity和Fragment已經(jīng)實(shí)現(xiàn)了LifecycleOwner接口媳板。

public interface LifecycleOwner {
    /**
     * Returns the Lifecycle of the provider
     * @return The lifecycle of the provider.
     */
    @NonNull
    Lifecycle getLifecycle();
}
public class Fragment implements implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner {
    ... ...
   LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }
    ... ...
}
public class FragmentActivity extends BaseFragmentActivityApi16 implements
        ActivityCompat.OnRequestPermissionsResultCallback,
        ActivityCompat.RequestPermissionsRequestCodeValidator {
    ... ...
    // FragmentActivity最終繼承自SupportActivity
   @Override
    public Lifecycle getLifecycle() {
        return super.getLifecycle();
    }
    ... ...
}
public class SupportActivity extends Activity implements LifecycleOwner {
    ... ...
    private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }
    ... ...
}

有上述源碼可以桑腮,其實(shí)getLifecycle() 方法最終返回的都是LifecycleRegistry對(duì)象,事件分發(fā)最后也都是調(diào)用LifecycleRegistry的handleLifecycleEvent()方法蛉幸。

    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;
    }
    private void sync() {
        LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
        if (lifecycleOwner == null) {
            Log.w(LOG_TAG, "LifecycleOwner is garbage collected, you shouldn't try dispatch "
                    + "new events from it.");
            return;
        }
        while (!isSynced()) {
            mNewEventOccurred = false;
            // no need to check eldest for nullability, because isSynced does it for us.
            if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
                backwardPass(lifecycleOwner);
            }
            Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
            if (!mNewEventOccurred && newest != null
                    && mState.compareTo(newest.getValue().mState) > 0) {
                forwardPass(lifecycleOwner);
            }
        }
        mNewEventOccurred = false;
    }
    private void forwardPass(LifecycleOwner lifecycleOwner) {
        Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
                mObserverMap.iteratorWithAdditions();
        while (ascendingIterator.hasNext() && !mNewEventOccurred) {
            Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
            ObserverWithState observer = entry.getValue();
            while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                    && mObserverMap.contains(entry.getKey()))) {
                pushParentState(observer.mState);
                observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
                popParentState();
            }
        }
    }

    private void backwardPass(LifecycleOwner lifecycleOwner) {
        Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
                mObserverMap.descendingIterator();
        while (descendingIterator.hasNext() && !mNewEventOccurred) {
            Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
            ObserverWithState observer = entry.getValue();
            while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
                    && mObserverMap.contains(entry.getKey()))) {
                Event event = downEvent(observer.mState);
                pushParentState(getStateAfter(event));
                observer.dispatchEvent(lifecycleOwner, event);
                popParentState();
            }
        }
    }

這些只是分發(fā)的邏輯破讨,那么在事件分發(fā)之前,肯定要有事件的注冊(cè)奕纫,這就得看一下addObserver()方法提陶。

    @Override
    public void addObserver(@NonNull LifecycleObserver observer) {
        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);
            statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
            popParentState();
            // mState / subling may have been changed recalculate
            targetState = calculateTargetState(observer);
        }

        if (!isReentrance) {
            // we do sync only on the top level.
            sync();
        }
        mAddingObserverCounter--;
    }
    static class ObserverWithState {
        State mState;
        GenericLifecycleObserver mLifecycleObserver;

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

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

至此,我們可以知道匹层,當(dāng)lifecycle發(fā)生變化時(shí)隙笆,handleLifecycleEvent
會(huì)通過 getStateAfter()方法獲取當(dāng)前應(yīng)處的狀態(tài)并修改mState值,緊接著遍歷所有 ObserverWithState并調(diào)用他們的sync方法來同步且通知LifecycleObserver狀態(tài)發(fā)生變化。

總結(jié)

Lifecycle生命周期事件感知由LifecycleDispatcher(ActivityLifecycleCallbacks, FragmentLifecycleCallbacks, Fragment)完成撑柔,并通過 LifecycleRegistry傳遞給 LifecycleObserver煤率。

鏈接:http://www.reibang.com/p/f3160cf00e49

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市乏冀,隨后出現(xiàn)的幾起案子蝶糯,更是在濱河造成了極大的恐慌,老刑警劉巖辆沦,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昼捍,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡肢扯,警方通過查閱死者的電腦和手機(jī)妒茬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蔚晨,“玉大人乍钻,你說我怎么就攤上這事∶螅” “怎么了银择?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)累舷。 經(jīng)常有香客問我浩考,道長(zhǎng),這世上最難降的妖魔是什么被盈? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任析孽,我火速辦了婚禮,結(jié)果婚禮上只怎,老公的妹妹穿的比我還像新娘袜瞬。我一直安慰自己,他們只是感情好身堡,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布邓尤。 她就那樣靜靜地躺著,像睡著了一般盾沫。 火紅的嫁衣襯著肌膚如雪裁赠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天赴精,我揣著相機(jī)與錄音佩捞,去河邊找鬼。 笑死蕾哟,一個(gè)胖子當(dāng)著我的面吹牛一忱,可吹牛的內(nèi)容都是我干的莲蜘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼帘营,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼票渠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起芬迄,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤问顷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后禀梳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體杜窄,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年算途,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了塞耕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嘴瓤,死狀恐怖扫外,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情廓脆,我是刑警寧澤筛谚,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站狞贱,受9級(jí)特大地震影響刻获,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瞎嬉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望厚柳。 院中可真熱鬧氧枣,春花似錦、人聲如沸别垮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽碳想。三九已至烧董,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胧奔,已是汗流浹背逊移。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留龙填,地道東北人胳泉。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓拐叉,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親扇商。 傳聞我的和親對(duì)象是個(gè)殘疾皇子凤瘦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容