首頁>技術>

將依賴於生命週期的程式碼直接寫在Activity 或 Fragment 會導致程式碼條理性很差並且會擴散錯誤。

透過Lifecycle可以將依賴元件的程式碼從生命週期方法移入元件本身中。也就是說,元件內部可以感知到Activity 或者 Fragment的生命週期

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

預備知識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;        }    }

官方註釋告訴我們

你可以將 States 想成一張圖中的點,將 Event 想成是圖中連線這些點的邊。

也就是這一張圖:

至於這張圖的箭頭和狀態是怎麼來的,可以在原始碼中(LifecycleRegister)找到答案:

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)也說明了上圖中的關係,讀者有興趣的話可以自己檢視原始碼

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

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

LifecycleOwner
public interface LifecycleOwner {        @NonNull    Lifecycle getLifecycle();}

單一方法的介面,顧名思義:可以將實現了這個介面的類理解為 具有Lifecycle的元件。可以很容易的想到 Activity 和 Fragment 已經實現了這個介面:

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不是隻有這一種方法。已經提供了幾種內建實現供我們選擇:比如官方已經內建實現了LifecycleObserver的 LifecycleEventObservser

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事件,而我們在Activity的onResume才註冊觀察者,還能收到發生在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 事件")            }        ...}

然後在Activity的onResume時才註冊觀察者

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

答案是:可以。所以大家放心使用

6
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • OAuth:每次授權暗中保護你的那個“MAN”