JetPack:Lifecycle

前言

因為最近沒有什么項目家夺,所以有時間研究了一下Andorid得JetPack擦俐,打開Android開發(fā)這平臺望薄,找到JetPack專欄,可以看到這樣得介紹:

Jetpack 是一套庫审洞、工具和指南莱睁,可幫助開發(fā)者更輕松地編寫優(yōu)質(zhì)應(yīng)用。這些組件可幫助您遵循最佳做法芒澜、讓您擺脫編寫樣板代碼的工作并簡化復(fù)雜任務(wù)仰剿,以便您將精力集中放在所需的代碼上。

Jetpack 包含與平臺 API 解除捆綁的 androidx.* 軟件包庫撰糠。這意味著酥馍,它可以提供向后兼容性辩昆,且比 Android 平臺的更新頻率更高阅酪,以此確保您始終可以獲取最新且最好的 Jetpack 組件版本。

附上鏈接:https://developer.android.google.cn/jetpack

簡而言之汁针,JetPack就是Google為了規(guī)范Android開發(fā)术辐,解決之前Android開發(fā)各種庫使用碎片化得問題,提出來的一套數(shù)據(jù)庫施无,生命周期管理等等一整套完整得庫辉词,可以這樣說,當(dāng)時真正走進(jìn)JetPack得時候猾骡,只有兩個字 ’真香’

本文是JetPack得一個系列瑞躺,首先介紹一下最常用得庫Lifecycle

Lifecycle篇

一 什么是Lifecycle

學(xué)習(xí)Lifecycle之前,首先我們應(yīng)該明白什么是Lifecycle兴想,學(xué)習(xí)一個東西最好的辦法就是去看官方文檔幢哨,打開Lifecycle專欄,可以看到如下幾個大字來介紹Lifecycle:

使用生命周期感知型組件處理生命周期

其實就是運用觀察者模式嫂便,來觀察Acitivity捞镰,F(xiàn)ragment等具有生命周期得控件,好處就是優(yōu)化我們代碼,避免內(nèi)存泄漏等一系列得問題岸售。

二 如何使用Lifecycle

Lifecycle得使用其實很簡單践樱,LifecycleObserver觀察者,LifecycleOwner被觀察者凸丸,只需要觀察者去訂閱被觀察者就行拷邢。

1,觀察者實現(xiàn)LifecycleObserver, 創(chuàng)建需要感知得生命周期方法屎慢,并加上@OnLifecycleEvent注解

public class BasePresenter<T extends IBaseView> implements LifecycleObserver {
    
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    void onCreateX(LifecycleOwner owner) {

    }
}

2, 被觀察者實現(xiàn)LifecycleOwner接口解孙,因為Activity最終父類ComponentActivity實現(xiàn)了LifecycleOwner接口,所以任意Activity在Lifecycle框架中都是一個被觀察者抛人。

3弛姜,建立訂閱關(guān)系:

protected void init() {
    activity.getLifecycle().addObserver(BasePresenter);
}

只需要以上3步,觀察者就可以感知到被觀察者得生命周期妖枚,是不是非常簡單實用廷臼。

三 Lifecycle得原理

在通常開發(fā)中,一般我們掌握如何使用就可以開始開發(fā)了绝页,但是作為一個努力進(jìn)步得程序員荠商,知其然也要知其所以然是我們拔高得必走之路,源碼雖然枯燥续誉,但是了解源碼得思想也是非常重要得一步莱没。讓我們一起看看Lifecyle是如何關(guān)聯(lián)生命周期得:

1,首先我們來看ComponentActivity酷鸦,因為ComponentActivity實現(xiàn)LifecycleOwner接口饰躲,所以讓應(yīng)用運行時,肯定會先走ComponentActivity得onCreate臼隔,查看onCreate獲取可以找到答案(以下代碼只貼上關(guān)鍵代碼):

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ReportFragment.injectIfNeededIn(this);
}
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();
            // Hopefully, we are the first to make a transaction.
            manager.executePendingTransactions();
        }
    }

讓我們點開injectIfNeededIn方法嘹裂,該方法創(chuàng)建了一個沒有界面得ReportFragment,查看ReportFragment可以發(fā)現(xiàn)摔握,該Fragment關(guān)聯(lián)者Activity得生命周期寄狼,切在每個生命周期方法中都會調(diào)用dispatch()方法,所以我們可以繼續(xù)往下跟:

private void dispatch(Lifecycle.Event event) {
        ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
}

看到目前為止氨淌,我們應(yīng)該知道一件事情泊愧,那就是在ComponentActivity中創(chuàng)建了一個沒有界面得Fragment關(guān)聯(lián)這activity生命周期,且每個生命周期方法都調(diào)用了 dispatch方法盛正。

所以我們繼續(xù)查看dispatch:

public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    State next = getStateAfter(event);
    moveToState(next);
}

private void moveToState(State next) {
        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);
            }
        }
    }
}

看到這里可以看到兩個方法backwardPass(),forwardPass(),其實這兩個方法做了同一個事情删咱,同步狀態(tài)。

在Lifecycle中維護(hù)了一組枚舉類型蛮艰,Event和State

public enum Event {
    ON_CREATE,
    ON_START,
    ON_RESUME,
    ON_PAUSE,
    ON_STOP,
    ON_DESTROY,
    ON_ANY
}
public enum State {
    DESTROYED,
    INITIALIZED,
    CREATED,
    STARTED,
    RESUMED;
    public boolean isAtLeast(@NonNull State state) {
        return compareTo(state) >= 0;
    }
}

而我們在上面看到得disPatch就是為了讓二者狀態(tài)統(tǒng)一

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;
    }

明白這個狀態(tài)以后我們繼續(xù)玩下看:forwardPass();

private void forwardPass(LifecycleOwner lifecycleOwner) {
        while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            pushParentState(observer.mState);
            observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
            popParentState();
        }
    }
}
void dispatchEvent(LifecycleOwner owner, Event event) {
    State newState = getStateAfter(event);
    mState = min(mState, newState);
    mLifecycleObserver.onStateChanged(owner, event);
    mState = newState;
}
@Override
public void onStateChanged(LifecycleOwner source, Event event) {
    mInfo.invokeCallbacks(source, event, mWrapped);
}

看到invokeCallbacks腋腮,我們就可以猜測是通過反射來獲取生命周期得方法雀彼,然后調(diào)用方法,往下跟:

void invokeCallback(LifecycleOwner source, Lifecycle.Event event, Object target) {
    //noinspection TryWithIdenticalCatches
    try {
        switch (mCallType) {
            case CALL_TYPE_NO_ARG:
                mMethod.invoke(target);
                break;
            case CALL_TYPE_PROVIDER:
                mMethod.invoke(target, source);
                break;
            case CALL_TYPE_PROVIDER_WITH_EVENT:
                mMethod.invoke(target, source, event);
                break;
        }
    }

看到這里被觀察者所做的邏輯基本清楚了即寡,利用放射原理徊哑,然后判斷方法對應(yīng)的參數(shù)有幾個,調(diào)用對應(yīng)的方法聪富,是的觀察者中的回到被調(diào)用莺丑!

而我們的反射得到的參數(shù)和方法是哪里來的呢,接下來帶著這個疑問墩蔓,讓我們看一下getLifecycle().addObserver(presenter);訂閱事件到底做了什么:

public void addObserver(@NonNull LifecycleObserver observer) {
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

調(diào)用addObserver方法梢莽,首先記錄當(dāng)前的狀態(tài),然后嗲這狀態(tài)信息和被觀察者包裝到ObserverWithState中奸披,

然后我們看看ObserverWithState類:

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;
    }
}

是不是很熟悉昏名,在上面的forwardPass方法中最終的回調(diào)也是到這里。

在訂閱的時候阵面,我們把被觀察者信息轻局,和狀態(tài)存到ObserverWithState中并調(diào)用了lifecycleEventObserver

lifecycleEventObserver中,最終會調(diào)用到createInfo方法:

for (Method method : methods) {
    OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);
    Class<?>[] params = method.getParameterTypes();
    int callType = CALL_TYPE_NO_ARG;
    if (params.length > 0) {
        callType = CALL_TYPE_PROVIDER;
    }
    Lifecycle.Event event = annotation.value();

    if (params.length > 1) {
        callType = CALL_TYPE_PROVIDER_WITH_EVENT;
     
    }

}

在這個方法中样刷,會通過method.getAnnotation(OnLifecycleEvent.class); 判斷是不是Lifecycle訂閱的注解仑扑,然后獲取每個方法的參數(shù)并賦值給callType = CALL_TYPE_PROVIDER; 然后在invokeCallbacks中調(diào)用。

以上就是整個Lifecycle的流程和原理置鼻。

結(jié)語

每當(dāng)自己總結(jié)這些原理性的東西的時候镇饮,表達(dá)總是不夠太好,感覺也有可能是自己理解還不是那么深刻的原因箕母,學(xué)無止境储藐,越往下學(xué)就越感覺到自己得無知,所以我也只是希望能通過這些細(xì)微得沉淀司蔬,慢慢讓自己形成一個大的知識體系吧邑茄。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市俊啼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌左医,老刑警劉巖授帕,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異浮梢,居然都是意外死亡跛十,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門秕硝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芥映,“玉大人,你說我怎么就攤上這事∧纹” “怎么了坞嘀?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長惊来。 經(jīng)常有香客問我丽涩,道長,這世上最難降的妖魔是什么裁蚁? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任矢渊,我火速辦了婚禮,結(jié)果婚禮上枉证,老公的妹妹穿的比我還像新娘矮男。我一直安慰自己,他們只是感情好室谚,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布昂灵。 她就那樣靜靜地躺著,像睡著了一般舞萄。 火紅的嫁衣襯著肌膚如雪眨补。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天倒脓,我揣著相機與錄音撑螺,去河邊找鬼。 笑死崎弃,一個胖子當(dāng)著我的面吹牛甘晤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播饲做,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼线婚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了盆均?” 一聲冷哼從身側(cè)響起塞弊,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎泪姨,沒想到半個月后游沿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡肮砾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年诀黍,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仗处。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡眯勾,死狀恐怖枣宫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吃环,我是刑警寧澤也颤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站模叙,受9級特大地震影響歇拆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜范咨,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一故觅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧渠啊,春花似錦输吏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至躲查,卻和暖如春它浅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背镣煮。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工姐霍, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人典唇。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓镊折,卻偏偏與公主長得像,于是被迫代替她去往敵國和親介衔。 傳聞我的和親對象是個殘疾皇子恨胚,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354