Android jetpack - Lifecycle 生命周期感知組件

一、前言

Lifecycle 生命周期感知控件屬于谷歌在2018推出Android jetpack(外網(wǎng))其中的軟件架構(gòu)組件中的一個也榄。在谷歌開發(fā)者網(wǎng)站有介紹Lifecycle(外網(wǎng))趟脂。本文指在介紹Lifecycle的使用。讓你快速理解并上手Lifecycle庫抢韭。雖然Lifecycle很簡單薪贫,但我們還是應該仔細品一品。因為jetpack中太多庫依賴這種聲明周期管理了刻恭。

二瞧省、Lifecycle

谷歌爸爸是這么說的:生命周期感知型組件可執(zhí)行操作來響應另一個組件(如 Activity 和 Fragment)的生命周期狀態(tài)的變化。這些組件有助于您寫出更有條理且往往更精簡的代碼鳍贾,這樣的代碼更易于維護鞍匾。
簡單理解下:把聲明周期用觀察者模式來監(jiān)聽。把以前跟聲明周期相關(guān)操作代碼提出來寫骑科。
在介紹Lifecycle的兩種用法前橡淑,我們需要先導入。其它用法請參看Lifecycle 版本說明(外網(wǎng))

// Lifecycles only (without ViewModel or LiveData)
implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"

基本使用

三個步驟就可以使用起來了咆爽,就是普通觀察者模式的三個步驟梁棠。
1、創(chuàng)建一個被觀察者Lifecycle對象
2伍掀、創(chuàng)建一個或多個觀察者LifecycleObserver對象
3掰茶、Lifecycle.addObserver把一個或多個LifecycleObserver觀察者添加
第一步:創(chuàng)建Lifecycle

public class MyActivity extends Activity implements LifecycleOwner {

    private LifecycleRegistry mLifecycleRegistry;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mLifecycleRegistry = new LifecycleRegistry(this);
        mLifecycleRegistry.markState(Lifecycle.State.CREATED);
    }

    @Override
    protected void onStart() {
        super.onStart();
        mLifecycleRegistry.markState(Lifecycle.State.STARTED);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mLifecycleRegistry.markState(Lifecycle.State.DESTROYED);
    }

    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }
}
  • Lifecycle是一個抽象類,LifecycleRegistry就是它的一個具體實現(xiàn)
  • LifecycleOwner接口蜜笤,就定義了一個getLifecycle濒蒋,方便獲取被觀察者。它存在的意義表示你的Activity或者Fragement具有Lifecycle特性把兔。很多依賴Lifecycle的組件就是通過這里來判斷的沪伙。
  • mLifecycleRegistry.markState為了綁定狀態(tài),綁定了才好通知觀察者
    第二步:創(chuàng)建LifecycleObserver觀察者
public class MyObserver implements LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void start() {

    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void destroy() {

    }
}
  • LifecycleObserver是一個空接口县好,目的是為了方便注解使用
    第三步:添加觀察者

mLifecycleRegistry.addObserver(new MyObserver());
if (mLifecycleRegistry.getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
    // do...
}
  • addObserver添加就能監(jiān)聽了
  • getCurrentState().isAtLeast提供了狀態(tài)的查詢
    State和Event對應關(guān)系
    三個步驟就完了围橡,比較簡單。細心的同學發(fā)現(xiàn)了缕贡,我們mark的時候狀態(tài)是Lifecycle.State翁授。而在觀察者狀態(tài)是Lifecycle.Event那么他們的對應關(guān)系如下圖:
    關(guān)系圖

常規(guī)情況
上面講的用法是我們使用的普通的Activity拣播,而實際開發(fā)的時候,我們經(jīng)常使用的是MainActivity extends AppCompatActivityAppCompatActivity已經(jīng)默認為我們實現(xiàn)了Lifecycle收擦。所以我們可以少些上面的第一步直接在MainActivity中使用getLifecycle()獲取被觀察者Lifecycle對象
再者如果你引用的是androidx中的Activity和Fragment他們也實現(xiàn)了Lifcycle的代碼贮配。

三、原理

對原理沒興趣的同學可以直接跳過這一節(jié)塞赂。
Lifecycle的運行機制也比較簡單泪勒,無非就是觀察者模式的慣用套路。我們也按步驟來解析
先看LifecycleRegistry.java

@Deprecated
    @MainThread
    public void markState(@NonNull State state) {
        setCurrentState(state);
    }

@MainThread
    public void setCurrentState(@NonNull State state) {
        moveToState(state);
    }

private void moveToState(State next) {
        ...
        sync();
       ...
    }

private void sync() {
        ...
        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();
            }
        }
    }
  • 1.我們再Activity里調(diào)用martState的時候就是響應的時候
  • 2.根據(jù)martState的調(diào)用順序宴猾,最后走到了backwardPassforwardPass他們類似
  • 3.在forwardPass里圆存,它遍歷了觀察者,調(diào)用了觀察者的dispatchEvent方法仇哆。
static class ObserverWithState {
        State mState;
        LifecycleEventObserver mLifecycleObserver;

        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;
        }
    }
  • 這里主要兩點Lifecycling.lifecycleEventObserveronStateChanged沦辙,而lifecycleEventObserver主要生成注解解析相關(guān)類
@NonNull
    static LifecycleEventObserver lifecycleEventObserver(Object object) {
        ...
        return new ReflectiveGenericLifecycleObserver(object);
    }
class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver {
    private final Object mWrapped;
    private final CallbackInfo mInfo;

    ReflectiveGenericLifecycleObserver(Object wrapped) {
        mWrapped = wrapped;
        mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
    }

    @Override
    public void onStateChanged(LifecycleOwner source, Event event) {
        mInfo.invokeCallbacks(source, event, mWrapped);
    }
}

通過反射調(diào)用就響應到了我們的方法上。

四税产、寫在最后

簡單的來看怕轿,Lifecycle通過觀察者模式獨立了生命周期的感知功能。一者方便了我們獨立的使用辟拷。二者也給一些需要生命周期感知的其它的組件提供了基礎(chǔ)撞羽。還是挺有意思的一個組件。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末衫冻,一起剝皮案震驚了整個濱河市诀紊,隨后出現(xiàn)的幾起案子隅俘,更是在濱河造成了極大的恐慌邻奠,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件为居,死亡現(xiàn)場離奇詭異蒙畴,居然都是意外死亡,警方通過查閱死者的電腦和手機膳凝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門碑隆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蹬音,你說我怎么就攤上這事上煤。” “怎么了著淆?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵劫狠,是天一觀的道長拴疤。 經(jīng)常有香客問我,道長嘉熊,這世上最難降的妖魔是什么遥赚? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮阐肤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘讲坎。我一直安慰自己孕惜,他們只是感情好,可當我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布晨炕。 她就那樣靜靜地躺著衫画,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瓮栗。 梳的紋絲不亂的頭發(fā)上削罩,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天,我揣著相機與錄音费奸,去河邊找鬼弥激。 笑死,一個胖子當著我的面吹牛愿阐,可吹牛的內(nèi)容都是我干的微服。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼缨历,長吁一口氣:“原來是場噩夢啊……” “哼以蕴!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起辛孵,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤丛肮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后魄缚,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宝与,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年鲜滩,在試婚紗的時候發(fā)現(xiàn)自己被綠了伴鳖。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡徙硅,死狀恐怖榜聂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嗓蘑,我是刑警寧澤须肆,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布匿乃,位于F島的核電站,受9級特大地震影響豌汇,放射性物質(zhì)發(fā)生泄漏幢炸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一拒贱、第九天 我趴在偏房一處隱蔽的房頂上張望宛徊。 院中可真熱鬧,春花似錦逻澳、人聲如沸闸天。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽苞氮。三九已至,卻和暖如春瓤逼,著一層夾襖步出監(jiān)牢的瞬間笼吟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工霸旗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留贷帮,地道東北人。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓定硝,卻偏偏與公主長得像皿桑,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蔬啡,可洞房花燭夜當晚...
    茶點故事閱讀 44,647評論 2 354

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