Android Jetpack 架構組件之 Lifecycle (二) 使用

Lifecycle 使用

在 上篇文章 Lifecycle(一) 起源中已經經過一個例子讓你們簡單的認識到:java

將依賴於生命週期的代碼直接寫在ActivityFragment 會致使代碼條理性不好而且會擴散錯誤。node

經過Lifecycle能夠將依賴組件的代碼從生命週期方法移入組件自己中。
也就是說,組件內部能夠感知到Activity 或者 Fragment的生命週期android

這篇文章具體展開說一下Lifecycle 的用法markdown

預備知識

Lifecycle 中的事件和狀態

Lifecycle 經過兩個枚舉類型:Event 和 State 來 對應 Android 視圖組件的生命週期:架構

// 事件
    public enum Event {
            ON_CREATE,
            ON_START,
            ON_RESUME,
            ON_PAUSE,
            ON_STOP,
            ON_DESTROY,
            ON_ANY
        }
    //狀態
    /** * Lifecycle states. You can consider the states as the nodes in a graph and * {@link Event}s as the edges between these nodes. */
    public enum State {
        DESTROYED,
        INITIALIZED,
        CREATED,
        STARTED,
        RESUMED;

        public boolean isAtLeast(@NonNull State state) {
            return compareTo(state) >= 0;
        }
    }
複製代碼

官方註釋告訴咱們app

你能夠將 States 想成一張圖中的點,將 Event 想成是圖中鏈接這些點的邊。ide

也就是這一張圖: 至於這張圖的箭頭和狀態是怎麼來的,能夠在源碼中(LifecycleRegister)找到答案:post

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;
        }
        throw new IllegalArgumentException("Unexpected event value " + event);
    }
複製代碼

邏輯很清楚的能夠對應到圖中的狀態與事件的轉換,另外還有兩個方法:downEvent(State state) upEvent(State state)也說明了上圖中的關係,讀者有興趣的話能夠本身查看源碼spa

  • 每個 Event 映射到Activity或者Fragmnet的其中一個生命週期的回調
  • 每個 State 反應了由 Lifecycle 跟蹤組件的當前狀態

⚠️ 不要把Lifecycle想得很神奇,其實質就是簡單的觀察者模式,首先在視圖控制器中註冊觀察者,Android源碼會在生命週期變化後去分發對應生命週期的事件,由LifecycleRegister去調用本身實現的LifecycleEventObserver(上面經過註解方法實現的LifecycleObserve最終也會被解析成LifecycleEventObserver)中的onStateChanged方法。具體原理會在Lifecycle第三篇說到code

LifecycleOwner

public interface LifecycleOwner {
    
    @NonNull
    Lifecycle getLifecycle();
}
複製代碼

單一方法的接口,顧名思義:能夠將實現了這個接口的類理解爲 具備Lifecycle的組件。能夠很容易的想到 ActivityFragment 已經實現了這個接口:

public class ComponentActivity extends androidx.core.app.ComponentActivity implements LifecycleOwner, ViewModelStoreOwner, ... 複製代碼
public class Fragment implements LifecycleOwner, ViewModelStoreOwner ... 複製代碼

因此在使用Lifecycle時能夠在Activity或Fragment中直接調用接口方法getLifecycle()

lifecycle.addObserver(NetStateManager)
複製代碼

添加觀察者

除此以外,咱們也能夠經過實現LifecycleOwner來自定義,在Lifecycle系列文章的最後會實現一個自定義LifeOwner幫助你們更好理解

LifecycleObserver

使用Lifecycle的第一步就是要實現LifecycleObserver

object ContentPlayer : LifecycleObserver{

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun prepare(context: Context) {
        //播放器的準備工做
    }
    
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun unAttach() {
        //釋放當前持有的Activity資源
    }
    
    // 開始播放
    fun Play(content: String) {
    	...
    }
    ...
}

複製代碼

經過方法註釋,明確指定該方法被調用的時機。在上面的例子中,若是在Acitivity中添加ContentPlayer觀察者,那麼perpare()方法會在Activity建立時調用,unAttach()會在Activity銷燬時調用。

實現LifecycleObserver不是隻有這一種方法。已經提供了幾種內置實現供咱們選擇:好比官方已經內置實現了LifecycleObserverLifecycleEventObservser

object ContentPlayer : LifecycleEventObserver {
    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        when (event) {
            Lifecycle.Event.ON_CREATE -> TODO()
            Lifecycle.Event.ON_START -> TODO()
            Lifecycle.Event.ON_RESUME -> TODO()
            Lifecycle.Event.ON_PAUSE -> TODO()
            Lifecycle.Event.ON_STOP -> TODO()
            Lifecycle.Event.ON_DESTROY -> TODO()
            Lifecycle.Event.ON_ANY -> TODO()
        }
    }
}
複製代碼

每當視圖控制器的狀態發生改變,都會將事件回調給onStateChanged(),在不一樣的事件分支中實現本身想要實現的邏輯。

實際上在使用第一種使用註解的方法的狀況下,在運行時LifecycleRegister這個類會經過反射或者apt來將LifecycleObserver轉化成LifecycleEventObservser,因此有些狀況下爲了不反射帶來的消耗,能夠優先考慮實現LifecycleEventObservser

添加觀察者

最後只須要在Activity的onCreated方法完成最後一步:

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

最後須要考慮一種狀況:若是在Observser中觀察了ON_CREATE事件,而咱們在ActivityonResume才註冊觀察者,還能收到發生在onResume()以前的ON_CREATE事件嗎?

object Observer : LifecycleObserver{

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun onCreate(context: Context) {
        
        Log.d(TAG, "觀察onCreate 事件")
        
    }
    
    @OnLifecycleEvent(Lifecycle.Event.ON_Start)
    fun onStart(context: Context) {
        
        Log.d(TAG, "觀察onStart 事件")
        
    }
    
    ...
}

複製代碼

而後在ActivityonResume時才註冊觀察者

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

答案是:能夠。因此你們放心使用

相關文章
相關標籤/搜索