Android架構(gòu)組件之Lifecycle源碼解析

Lifecycle-Aware是Google官方的生命周期感知組件。同時,在Google推出的Android Jetpack組件中骄瓣,也將Lifecycle-Aware放在了Architecture類別之中械馆。我們可以利用 android.arch.lifecycle 包提供的類來控制數(shù)據(jù)、監(jiān)聽器等的 lifecycle厌杜。同時奉呛,LiveData和ViewModel的lifecycle也依賴于Lifecycle框架计螺,所以我們有必要去了解一下Lifecycle。

Google官方Lifecycle組件跟蹤狀態(tài)圖

一瞧壮、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()方法其實就是在Application中注冊了一個ActivityLifecycleCallbacks監(jiān)聽(即DispatcherActivityCallback)半等,用來監(jiān)聽每個Activity的生命周期變化。
我們再看下DispatcherActivityCallback的onActivityCreated()回調(diào)方法呐萨,如果Activity是FragmentActivity杀饵,則注冊一個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如果實現(xiàn)了LifecycleRegistryOwner切距,就會為其添加一個DestructionReportFragment,用來監(jiān)聽Fragment的生命周期惨远。
之后谜悟,會在Activity中添加一個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);
            }
        }
    }

如此葡幸,利用一個附著在Activity上無UI的Fragment,通過相應(yīng)的生命周期回調(diào)方法贺氓,實質(zhì)上是對Activity生命周期的監(jiān)聽蔚叨。
至此,我們知道了Lifecycle組件通過ActivityLifecycleCallbacks辙培、FragmentLifecycleCallbacks及 無UI的Fragment來感知Activity/Fragment的生命周期變化并產(chǎn)生相應(yīng)的事件蔑水。

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

在上面的分析中扬蕊,我們只是重點關(guān)注了Lifecycle如何感知生命周期搀别,也就是如何監(jiān)聽Activity/Fragment的生命周期。在相應(yīng)的回調(diào)方法當(dāng)中厨相,其實都包含了很多生命周期事件分發(fā)相關(guān)的邏輯领曼。通過相關(guān)的源碼分析鸥鹉,我們可以發(fā)現(xiàn)最終都會調(diào)用到Activity/Fragment的getLifecycle()方法獲取Lifecycle對象,之后再調(diào)用Lifecycle對象的handleLifecycleEvent()方法進(jìn)行事件分發(fā)庶骄。26.1.0及更高版本Support支持庫中的Activity和Fragment已經(jīng)實現(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;
    }
    ... ...
}

有上述源碼可以,其實getLifecycle() 方法最終返回的都是LifecycleRegistry對象单刁,事件分發(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ā)之前羔飞,肯定要有事件的注冊肺樟,這就得看一下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ā)生變化時蚤假,handleLifecycleEvent
會通過 getStateAfter()方法獲取當(dāng)前應(yīng)處的狀態(tài)并修改mState值,緊接著遍歷所有 ObserverWithState并調(diào)用他們的sync方法來同步且通知LifecycleObserver狀態(tài)發(fā)生變化。

總結(jié)

Lifecycle生命周期事件感知由LifecycleDispatcher(ActivityLifecycleCallbacks, FragmentLifecycleCallbacks, Fragment)完成毫炉,并通過 LifecycleRegistry傳遞給 LifecycleObserver掘譬。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末粪牲,一起剝皮案震驚了整個濱河市爸黄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌擎鸠,老刑警劉巖缀磕,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異劣光,居然都是意外死亡袜蚕,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門赎线,熙熙樓的掌柜王于貴愁眉苦臉地迎上來廷没,“玉大人,你說我怎么就攤上這事垂寥。” “怎么了另锋?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵滞项,是天一觀的道長。 經(jīng)常有香客問我夭坪,道長文判,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任室梅,我火速辦了婚禮戏仓,結(jié)果婚禮上疚宇,老公的妹妹穿的比我還像新娘。我一直安慰自己赏殃,他們只是感情好敷待,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著仁热,像睡著了一般榜揖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上抗蠢,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天举哟,我揣著相機與錄音,去河邊找鬼迅矛。 笑死妨猩,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的秽褒。 我是一名探鬼主播壶硅,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼震嫉!你這毒婦竟也來了森瘪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤票堵,失蹤者是張志新(化名)和其女友劉穎扼睬,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悴势,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡窗宇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了特纤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片军俊。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖捧存,靈堂內(nèi)的尸體忽然破棺而出粪躬,到底是詐尸還是另有隱情,我是刑警寧澤昔穴,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布镰官,位于F島的核電站,受9級特大地震影響吗货,放射性物質(zhì)發(fā)生泄漏泳唠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一宙搬、第九天 我趴在偏房一處隱蔽的房頂上張望笨腥。 院中可真熱鬧拓哺,春花似錦、人聲如沸脖母。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽镶奉。三九已至础淤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間哨苛,已是汗流浹背鸽凶。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留建峭,地道東北人玻侥。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像亿蒸,于是被迫代替她去往敵國和親凑兰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345