Jetpack架構元件學習(1)——LifeCycle的使用

one發表於2021-11-19

原文地址:Jetpack架構元件學習(1)——LifeCycle的使用 | Stars-One的雜貨小窩

要看本系列其他文章,可訪問此連結Jetpack架構學習 | Stars-One的雜貨小窩

最近有時間了,準備入坑Jetpack架構,第一篇就學個簡單的LifeCycle,可以幫助開發者建立可感知生命週期的元件。

介紹

為什麼需要LifeCycle元件?

在很多情況下,我們需要在Activity的相關生命週期中進行相關的初始化操作,比如上一節說到的EventBus,需要在OnCreate()onDestroy()方法中進行繫結和解綁,我們可以使用此元件來簡化操作(下面的例子即是使用LifeCycle去簡化EventBus繫結Activity的操作)

LifeCycle的本質原理就是觀察者模式,其中有類LifecycleOwner(被觀察者)和介面LifecycleObserver(觀察者),通過觀察者模式,即可實現對頁面生命週期進行監聽,從而減低程式碼耦合度

這裡提下:

Support Library 26.1.0 及其以後的版本(含androidx),ActivityFragment 已經實現了LifecycleOwner 介面

所以,我們可以直接在Activity 和Fragment中使用getLifecycle()方法來獲取lifecycle物件,來新增觀察者監聽。

我是直接使用了androidx版本,所以基本使用是無需匯入額外的依賴

由於ActivityFragment實現了LifecycleOwner介面,所以,使用我們只需要建立我們的觀察者物件,與Activity進行繫結即可

基本使用

下面以EventBus的初始化來講解下使用方法

1.實現LifecycleObserver介面

前面也說到了,LifeCycle提供了一個介面類LifecycleObserver,這個介面裡沒有任何的方法,我們需要要定義個類去實現它,即可讓該類成為一個LifeCycle觀察者類

我們需要讓一個類去實現此介面,由於EventBus需要繫結Activity物件,所以我們需要類提供一個構造方法來接收Activity物件

class EventBusInitiator(val context: Context) : LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun register() {
        EventBus.getDefault().register(context)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun unregister() {
        EventBus.getDefault().unregister(context)
    }
}

那我們實現了介面類,如何讓Lifecycle回撥我們的方法呢?這裡Lifecycle設計就和EventBus有些異曲同工之妙了,也是提供註解的方式,從而Activity在進入對應的生命週期會回撥引數

OnLifecycleEvent註解裡的引數只接收對應的事件,事件有以下7種型別

  • ON_CREATE 匹配Activity的onCreate事件
  • ON_START 匹配Activity的onStart事件
  • ON_RESUME 匹配Activity的onResume事件
  • ON_PAUSE 匹配Activity的onStop事件
  • ON_STOP 匹配Activity的onStop事件
  • ON_DESTROY 匹配Activity的onDestroy事件
  • ON_ANY 可以匹配任何的事件(每次Activity的生命週期發生變化,都會呼叫一次)

前6種就是和Activity中的生命週期保持對應,最後一種有點迷,不知道具體是在哪種情況下使用的

PS:在這篇文章中提到Android 架構元件之 LifeCycle詳解 - SegmentFault 思否,有兩種方式用來實現LifeCycle的監聽

  • 實現DefultLifecyceObserver介面,然後重寫裡面生命週期方法;
  • 直接實現LifecycleObserver介面,然後通過註解的方式來接收生命週期的變化;

Lifecycle.java文件中是建議使用第一種方式,隨著Java8成為主流,註解的方式會被棄用。

這裡我也沒細找文件去研究,也不知道是不是這回事,就我個人感覺使用註解的方式會比較舒服,智者見智仁者見仁吧

2.Activity註冊觀察者物件

在上面實現LifecycleObserver介面後,我們就有個類,當Activity生命週期發生改變的話,就會將事件分發給類中,前提是我們得讓Activity註冊這個類的物件,程式碼如下所示

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_event_bus)

    lifecycle.addObserver(EventBusInitiator(this))
}

PS:如果是Java,是通過getLifecycle()方法獲取LifeCycle物件

效果與之前的例子一樣,點選按鈕即可改變文字

補充-判斷當前頁面狀態

LifeCycle中的狀態有以下5種型別:

  • Lifecycle.State.CREATED
  • Lifecycle.State.DESTROYED
  • Lifecycle.State.RESUMED
  • Lifecycle.State.STARTED
  • Lifecycle.State.INITIALIZED

INITIALIZED狀態表示的是初始化完成,但onCreate()週期未開始的狀態

而之後CREATED狀態,標明是onCreate()週期已結束的狀態,後面的依次類推

可以參考下面的LifeCycle狀態改變和事件的解析圖:

LifeCycle狀態改變和事件的解析圖

判斷的話我們可以使用LifeCycle物件的currentState狀態,如下程式碼:

//直接一個判斷就完事了
if (lifecycle.currentState == Lifecycle.State.INITIALIZED) {
    
}

//狀態至少要是CREATED
lifecycle.currentState.isAtLeast(Lifecycle.State.CREATED)

進階使用

進階使用中,需要引入依賴

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

LifecycleService的使用

上述的只講了Activity和Fragment的使用方法,如果我們想要Service中想要生命週期解耦,可以使用LifecycleService,其父類是Service,只不過裡面已經實現了LifecycleOwner介面,所以用法是基本一樣的

我們使用Android Studio快速新建一個Service

然後修改程式碼為下述程式碼:

class MyService : LifecycleService() {

    val TAG = "MyService"

    init {
        lifecycle.addObserver(MyServiceObserver())
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        //開啟服務就開啟個執行緒
        Log.d(TAG, "onStartCommand: 執行")
        thread {
            for (i in 0..5) {
                Log.d(TAG, "執行緒列印: $i")
                Thread.sleep(1000)
            }

        }
        return super.onStartCommand(intent, flags, startId)
    }

}

class MyServiceObserver() : LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun create() {
        Log.d("MyService", "Service中的oncreate方法執行了");
    }
}

Service的生命週期和上述Activity的例子一樣,這裡不再贅述,日誌列印如圖所示

PS:記得在Activity中使用startService開啟服務哦

想起來,之前還沒寫過Service的學習筆記? 之後有空補上

ProcessLifecycleOwner的使用

除了上面的情況,有時候我們需要判斷下APP是處於前臺或後臺,這個時候就可以使用ProcessLifecycleOwner,具體用法如下

需要我們自定義一個application,然後在其中註冊觀察者即可

class MyApplication: Application() {
    override fun onCreate() {
        super.onCreate()
        ProcessLifecycleOwner.get().lifecycle.addObserver(MyApplicationObserver())
    }
}

class MyApplicationObserver : LifecycleObserver{
    //在應用程式的整個生命週期中只會被呼叫一次
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun onCreate(){
        Log.e("application","Application onCreate方法執行了");
    }


    //在應用程式在前臺出現時被呼叫
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onStart(){
        Log.e("application","Application onStart方法執行了");
    }

    //在應用程式在前臺出現時被呼叫
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun onResume(){
        Log.e("application","Application onResume方法執行了");
    }

    //在應用程式退出到後臺時被呼叫
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun onPause(){
        Log.e("application","Application onPause方法執行了");
    }

    //在應用程式退出到後臺時被呼叫
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onStop(){
        Log.e("application","Application onStop方法執行了");
    }


    //永遠不會被呼叫,系統不會分發呼叫ON_DESTROY事件
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun onDestroy(){
        Log.e("application","Application onDestroy方法執行了");
    }
}

PS:記得在AndroidManifest中使用我們的這個自定義Application

日誌輸出如下圖所示:

參考

相關文章