原文地址: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
日誌輸出如下圖所示: