Jetpack架構組件學習(1)——LifeCycle的使用
原文地址: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),Activity
和Fragment
已經實現了LifecycleOwner
介面所以,我們可以直接在Activity 和Fragment中使用
getLifecycle()
方法來獲取lifecycle
對象,來添加觀察者監聽。
我是直接使用了androidx版本,所以基本使用是無需導入額外的依賴
由於Activity
和Fragment
實現了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
對象的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
日誌輸出如下圖所示:
參考
- Android架構之LifeCycle組件_冬瓜闖世界的部落格-CSDN部落格
- Android 架構組件之 LifeCycle詳解 – SegmentFault 思否
- Android官方架構組件Lifecycle:生命周期組件詳解&原理分析 – 簡書