一、 定義
Lifecycle
是一個類,用於存儲有關組件(如 Activity 或 Fragment)的生命週期狀態的信息,並允許其他對象觀察此狀態。
- 爲什麼需要
Lifecycle
?
在實際應用開發中,多數應用組件都存在生命週期,但是生命週期由操作系統和進程中運行的框架代碼管理,它們是Android運行方式的核心,應用必須遵循它們,如果不這樣做,可能會引發內存泄漏甚至應用崩潰
- 舉一個簡單的定位服務應用示例:
假如我們有一個屏幕上顯示設備位置的Activity,常規實現如下所示:
class MyLocationListener(
private val context: Context,
private val callback: (Location) -> Unit
) {
fun start() {
// connect to system location service
Log.d("lifecycle","MyLocationListener start")
}
fun stop() {
// disconnect from system location service
Log.d("lifecycle","MyLocationListener stop")
}
}
在Activity中通過接口回調來實現UI更新
class LifecycleActivity : AppCompatActivity() {
private lateinit var myLocationListener: MyLocationListener
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_lifecycle)
myLocationListener = MyLocationListener(this) {
//更新UI
}
}
override fun onStart() {
super.onStart()
myLocationListener.start()
}
override fun onStop() {
super.onStop()
myLocationListener.stop()
}
}
雖然此示例看起來沒問題,但在實際的應用中,定位功能會有太多界面和其他組件的調用,這樣寫會有啥問題?
-
在生命週期方法(如
onStart()
和onStop()
)中放置大量的代碼,顯得不太優雅且難以維護 -
在組件中做了耗時操作(比如在
onStart
方法),這種寫法就無法保證組件在Activity
或者Fragment
停止之前完成啓動。
因此我們需要一個能管理Activity和Fragment的生命週期的庫,這個庫就是Lifecycle
。
二、如何使用Lifecycle控件
- 舉一個使用Lifecycle的簡單例子
新建一個LastLocationListener
類,它實現了LifecycleObserver
接口,說明LastLocationListener
成爲了一個Lifecycle的觀察者。
class LastLocationListener :LifecycleObserver{
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun start() {
// connect to system location service
Log.d("lifecycle","LastLocationListener start")
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun stop() {
// disconnect from system location service
Log.d("lifecycle","LastLocationListener stop")
}
}
在Activity中實現觀察者註冊
class LifecycleActivity : AppCompatActivity() {
private lateinit var lastLocationListener: LastLocationListener
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_lifecycle)
// 註釋1
lastLocationListener = LastLocationListener()
lifecycle.addObserver(lastLocationListener)
}
}
然後在註釋1處將LastLocationListener添加到LifecycleOwner中。LifecycleOwner是一個接口,其內部只有一個方法getLifecycle(),getLifecycle方法用於獲取Lifecycle,這樣就可以將LastLocationListener添加到Lifecycle中,當Lifecycle的生命週期發生變化時,LastLocationListener就會觀察到,或者說是感知到。
- 日誌輸出:
簡單說明一下就是:
先實現LastLocationListener,對ON_START
和ON_STOP
事件進行監聽。因爲在Android Support Library 26.1.0
及其之後的版本,Activity和Fragment已經默認實現了LifecycleOwner
接口,所以在註釋1處可以直接使用getLifecycle
方法獲取Lifecycle
對象,這樣LastLocationListener
就可以觀察LifecycleActivity
的生命週期變化了,LifecycleOwner
可以理解爲被觀察者,默認實現了LifecycleOwner
接口,也就是說LifecycleActivity
是被觀察者。
只要在LifecycleActivity的onCreate方法中添加LastLocationListener,那麼LastLocationListener就可以觀察到LifecycleActivity
的各個生命週期的變化。
三、自定義LifecycleOwner
如果想實現自定義LifecycleOwner,可以使用LifecycleRegistry,它是Lifecycle的實現類。Android Support Library 26.1.0及其之後的版本,Activity和Fragment已經默認實現了LifecycleOwner接口,因此我們可以這麼寫:
package com.onexzgj.inspur.pageingsample.lifecycle
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import com.onexzgj.inspur.pageingsample.R
/**
* 自定義LifecycleOwner
*/
class MyLifecycleOwnerActivity : AppCompatActivity(), LifecycleOwner {
private lateinit var lifecycleRegistry: LifecycleRegistry
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my_lifecycle_owner)
lifecycleRegistry = LifecycleRegistry(this)
lifecycleRegistry.currentState = Lifecycle.State.CREATED
}
override fun getLifecycle(): Lifecycle {
return super.getLifecycle()
}
override fun onStart() {
super.onStart()
lifecycleRegistry.currentState = Lifecycle.State.STARTED
}
override fun onDestroy() {
super.onDestroy()
lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
}
}
通過新建LifecycleRegistry,爲LifecycleRegistry設置Lifecycle的各種狀態,並通過getLifecycle方法返回該LifecycleRegistry。
總結
這一篇介紹了Lifecycle的基本用法,並通過簡單案例來幫助大家消化理解,具體在項目中的使用也不難,唯一還算難點的是Lifecycle的原理,待後續更新更新Lifecycle的原理。
文章中的示例代碼見Jetpack_Component
##詳細介紹文章
項目目錄結構爲如下