一點點入坑JetPack:Lifecycle篇

前言 java

由於業務的緣由,本身也開始了JetPack之旅。不得不認可,用上以後:真香。 JetPack以官方的方案,解決了不少咱們頭疼的問題。JetPack做爲一整套的解決方案,不是一篇文章很夠解釋清楚的。正如官方所說:android

Android Jetpack 組件是庫的集合,這些庫是爲協同工做而構建的,不過也能夠單獨採用,同時利用 Kotlin 語言功能幫助您提升工做效率。可所有使用,也可混合搭配!面試

因此這將是一個系列文章,一點點的展開我在JatPack應用中的所學所想。(目前公司項目已將全面用Kotlin,JetPack進行了重構,所以不少代碼的設計會和咱們的業務相結合,因此仁者見仁智者見智啦~)app

一點點入坑JetPack:ViewModel篇框架

一點點入坑JetPack:Lifecycle篇ide

一點點入坑JetPack:LiveData篇post

一點點入坑JetPack:實戰前戲NetworkBoundResource篇學習

一點點入坑JetPack(終章):實戰MVVMui

文章重點部分將聚焦:this

正文

不想看我瞎比比的,也能夠直接跳轉至官網:developer.android.google.cn/topic/libra…

一、如何管理生命週期

Lifecycle的出現幫咱們解決生命週期管理的問題。這一塊對於咱們平常開發來講的確是比較坑的一點,生命週期處理不當,很容易形成內存泄漏。 爲了能讓咱們業務代碼可以感知到生命週期,咱們可能會寫大量的代碼。好比在讓Presenter擁有感知生命週期的能力,咱們可能會這麼作:

public interface IPresenter {
    void onCreate();

    void onStart();

    void onResume();

    void onPause();

    void onStop();

    void onDestroy();
}
複製代碼

而後實現接口,在Activity/Fragment的生命週期中調用這個接口,完成工做。

這種方式徹底ojbk。通俗易懂,這裏我不評價它的好壞,畢竟沒有任何一種解決方案是完美的。因此接下來我們來看一看官方的Lifecycle是怎樣的一種思路。


二、Lifecycle

說破天,這裏須要解決的問題是生命週期管理。那麼終究仍是逃脫不掉一些套路成分在其中。Lifecycle也是如此,從官方的解釋中,可見一斑:

Lifecycle is a class that holds the information about the lifecycle state of a component (like an activity or a fragment) and allows other objects to observe this state.

短短一段話,咱們能夠猜想到這裏經過觀察者模式的思路去對外響應生命週期變化。閒話少說,直接從代碼感覺一下。

2.一、使用

從使用上來講,仍是比較簡單的。實現LifecycleObserver接口:

// 官方demo
class MyObserver : LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun connectListener() {
        // TODO
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun disconnectListener() {
        // TODO
    }
}

複製代碼

這倆個註解則標誌着,當監聽組件的onResume()方法被調用,這裏咱們被註解的方法也會被調用。(固然前提是addObserver了)

有了觀察者了,那咱們就去找被觀察者。很明顯,咱們想要觀察的對象是擁有生命週期的傢伙,好比咱們經常使用的Activity/Fragment。此時咱們只須要在onResume()以前的某個實際,把這個Observer,add進去便可,好比在onCreate()中:

override fun onCreate(savedInstanceState: Bundle?) {
   lifecycle.addObserver(MyObserver())
}
複製代碼

OK,這樣以後咱們的MyObserver既能夠正常在響應對應生命週期註解下的方法了。

不過,我相信這樣寫的朋友,回過來噴我!根本就調不到lifecycle!!

沒錯,咱們常規的Activitiy/Fragment就是調不到...它壓根就沒這這個方法。

2.二、androidx

這裏解釋一下,上文中lifecyle其實就是調用Activity/Fragment中的這個方法:

@Override
public Lifecycle getLifecycle() {
    return mLifecycleRegistry;
}
複製代碼

有朋友應該提着刀過來了,我tm沒有這個方法!兄die,把刀放下,不是沒有是import不同。接下來讓咱們慢慢來。我使用的這個Fragment的package是這樣的:androidx.fragment.app;。看到端倪了吧?androidx,沒錯,這是爲了完美支持JatPack所從新規劃出來的包。

固然,也不必定非要用androidx。

Fragments and Activities in Support Library 26.1.0 and later already implement the LifecycleOwner interface.

因此,升庫就ok了。這時有小夥伴可能會說了:我不想升庫怎麼辦。這個問題問得好,不想升庫,不想升庫..就不升唄。

固然我相信,必定有小夥伴注意到一個問題,那就是getLifecycle()是一個接口,那麼也就是說咱們能夠本身實現?沒錯是這樣...(這tm不廢話麼)

這就是咱們自定義的關鍵。

2.三、LifecycleOwner

假設咱們的Activity不支持getLifecycle()咋整?這裏直接上官方的代碼:

class MyActivity : Activity(), LifecycleOwner {
    private lateinit var mLifecycleRegistry: LifecycleRegistry

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        mLifecycleRegistry = LifecycleRegistry(this)
        mLifecycleRegistry.markState(Lifecycle.State.CREATED)
        
        mLifecycleRegistry.addObserver(MyObserver())
    }

    public override fun onStart() {
        super.onStart()
        mLifecycleRegistry.markState(Lifecycle.State.STARTED)
    }

    override fun getLifecycle(): Lifecycle {
        return mLifecycleRegistry
    }
}
複製代碼

就這樣,結束了。說實話,到這就這的沒有什麼好講的了。

經過代碼,咱們能夠看出來,LifecycleRegistry是咱們的被觀察者,它被初始化在擁有生命週期的Activity中,而咱們的Observer也被add()到其中,此外還有諸如markState(Lifecycle.State.CREATED)的方法調用。

所以,到這無需多言,各位小夥伴恐怕已經明白了Lifecycle是如何幫咱們管理生命週期的了。

2.四、小總結

這幾段代碼下來,我相信有的朋友已經差很少了解Lifecycle的思路了。一個很標準的觀察者模式:這裏的LifecycleRegistry(系統幫咱們實現的Lifecycle的實現類),持有想要監聽這個LifecycleOwner的Observer。而後經過markState(),去遍歷全部Observer,通知其生命週期發生變化。


三、原理

聊完了普通用法,我們來看一下原理。不得不說,Lifecycle實現的原理仍是比較騷的,各類騷操做簡直是亂花漸欲迷人眼。

我們在上述的MyObserver中加了註解,因此先看看註解爲咱們帶來了什麼。經過註解生成器,咱們能夠看到在build中獲得了下邊這個class:

public class MyObserver_LifecycleAdapter implements GenericLifecycleObserver {
    final MyObserver mReceiver;

    LifecycleObserverDemo_LifecycleAdapter(MyObserver receiver) {
        this.mReceiver = receiver;
    }

    @Override
    public void onStateChanged(LifecycleOwner owner, Lifecycle.Event event) {
        mReceiver.onAny(owner,event);
        if (event == Lifecycle.Event.ON_RESUME) {
            mReceiver.connectListener();
        }

        if (event == Lifecycle.Event.ON_PAUSE) {
            mReceiver.disconnectListener();
        }
    }

    public Object getReceiver() {
        return mReceiver;
    }
}
複製代碼

很清晰,咱們可以看到,在onStateChanged(LifecycleOwner owner, Lifecycle.Event event)中經過對應的Event就能夠調用到咱們MyObserver中註解的方法。

那麼問題來了:onStateChanged被誰調用的呢?經過上邊的例子,咱們知道想要Observer可以感應生命週期要麼使用內置好的Lifecycle(getLifecycle()),要麼本身去實現(LifecycleOwner)。接下來我們就分這倆種狀況來看一看具體的實現原理。

3.一、自定義LifecycleOwner

這一步的源碼仍是比較的簡單直接的,咱們能夠直接在LifecycleRegistry中的markState(Lifecycle.State.STARTED)一探究竟,一層層的調用下來,咱們拋棄一些邏輯判斷以後,能夠看到一些關鍵的內容:

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;
    }
}
複製代碼

能夠看到,這部分會很直白的調用到註解生成class中的onStateChanged(),完成生命週期的感知。

3.二、getLifecycle()

getLifecycle()的方式,一樣是返回了一個LifecycleRegistry。所以,最開始我認爲系統所以在對應的生命週期完成對上3.1同樣的調用。不過看把發現本身仍是太年輕。

SupportActivity中,的onCreate方法中,咱們能夠看到這樣的調用:

protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ReportFragment.injectIfNeededIn(this);
}
複製代碼

是否是感受到一絲絲熟悉?使用Fragment作生命週期分離管理在不少框架中都出現。接下來咱們就好好看看這個ReportFragment

@Override
public void onResume() {
    super.onResume();
    dispatchResume(mProcessListener);
    dispatch(Lifecycle.Event.ON_RESUME);
}

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);
        }
    }
}
複製代碼

到此就從新回調到了LifecycleRegistry中的方法了。

尾聲

固然僅憑這些,對於咱們來講還遠遠不夠,所以Google還拿出了ViewModelLiveData等相輔相成的有趣模塊。下邊的文章將走進:ViewModel篇。

許久沒有寫文章了,一來是最近的確很忙;二來本身也剛開始搞JetPack這一套。學的過程當中漸漸發現JatPack屬實比較有意思。因此決定好好的把JetPack研究一翻。

這篇文章就算是本身迴歸寫文章的先導篇吧~

我是一個應屆生,最近和朋友們維護了一個公衆號,內容是咱們在從應屆生過渡到開發這一路所踩過的坑,以及咱們一步步學習的記錄,若是感興趣的朋友能夠關注一下,一同加油~

我的公衆號:IT面試填坑小分隊
相關文章
相關標籤/搜索