Android Jetpack架構元件——Lifecycle使用篇
概述
Lifecycle是一個持有元件生命週期狀態的class,並且允許其他元件來觀察生命週期的變化。並不侷限於Activity或者Fragment。我們只知道生命週期是由作業系統或者程序中執行的程式碼進行管理。而且生命週期是Android工作原理的核心,所以應用必須遵循它們。否則會引起OOM或者Crash。
為什麼需要使用Lifecycle管理生命週期
在此我們用官網提供的一個示例:
internal class MyLocationListener(
private val context: Context,
private val callback: (Location) -> Unit
) {
fun start() {
// connect to system location service
}
fun stop() {
// disconnect from system location service
}
}
class MyActivity : AppCompatActivity() {
private lateinit var myLocationListener: MyLocationListener
override fun onCreate(...) {
myLocationListener = MyLocationListener(this) { location ->
// update UI
}
}
public override fun onStart() {
super.onStart()
myLocationListener.start()
// manage other components that need to respond
// to the activity lifecycle
}
public override fun onStop() {
super.onStop()
myLocationListener.stop()
// manage other components that need to respond
// to the activity lifecycle
}
}
從邏輯上看這段程式碼其實沒什麼問題,但是在真實應用場景中,我們需要管理很多元件和當前頁面的呼叫,以響應當前生命週期的狀態。所以會導致我們在onStop和onStart中存放大量的程式碼,導致它們難以維護。
所以官方提供lifecycle就是為了可以幫助我們以彈性和隔離的方式解決這些問題。
如何使用Lifecycle
lifecycle依賴
如果需要使用lifecycle的依賴,需要家google的maven倉庫新增到專案中,在專案中的build.gradle新增:
allprojects {
repositories {
google()
}
}
在你的工程目錄中的build.gradle中新增如下依賴:
dependencies {
def lifecycle_version = "2.2.0"
def arch_version = "2.1.0"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// Lifecycles only (without ViewModel or LiveData)
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
// Saved state module for ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
// Annotation processor
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// alternately - if using Java8, use the following instead of lifecycle-compiler
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// optional - helpers for implementing LifecycleOwner in a Service
implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
// optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
// optional - ReactiveStreams support for LiveData
implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version"
// optional - Test helpers for LiveData
testImplementation "androidx.arch.core:core-testing:$arch_version"
}
使用方法
- 生命週期擁有者使用getLifecycle()或者例項,然後通過addObserver新增觀察者。
- 觀察者實現LifecycleObserver介面,通過使用OnLifecycleEvent註解關注相應的生命週期。
使用示例
我們這裡依然使用官方的例子:
class MyObserver : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun connectListener() {
...
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun disconnectListener() {
...
}
}
myLifecycleOwner.getLifecycle().addObserver(MyObserver())
首先MyObserver實現LifecycleObserver介面,並使用ON_RESUME和ON_PAUSE註解對方法加上了生命週期的限制。然後擁有者直接通過新增觀察者的形式進行呼叫即可。
實現自定義的LifecycleOwner
在26.1.0及更高版本中的Fragment和Activity已經預設實現了LifecycleOwner介面。
如果你需要自定義類並希望它成為LifecycleOwner。你可以使用 LifecycleRegistry。示例程式碼如下:
class MyActivity : Activity(), LifecycleOwner {
private lateinit var lifecycleRegistry: LifecycleRegistry
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleRegistry = LifecycleRegistry(this)
lifecycleRegistry.markState(Lifecycle.State.CREATED)
}
public override fun onStart() {
super.onStart()
lifecycleRegistry.markState(Lifecycle.State.STARTED)
}
override fun getLifecycle(): Lifecycle {
return lifecycleRegistry
}
}
通過makeState設定Lifecycle的各種狀態,然後通過getLifecycle返回該例項。
實戰
我們簡單通過lifecycle對應用的前後臺進行一個監聽。我們先看下我們使用lifecycle之前是怎麼對應用的前後臺監聽的。
/**
* @date:2020/12/30
* @author:Silence
* @describe:
**/
open class BaseActivityLifecycleCallback : Application.ActivityLifecycleCallbacks {
private var currentResumedActivity: WeakReference<Activity>? = null
//監聽app前後臺的監聽器
private var listener: OnAppStatusListener? = null
//開啟的Activity數量統計
private var activityStartCount = 0
fun registerAppStatusListener(listener: OnAppStatusListener) {
this.listener = listener
}
override fun onActivityPaused(activity: Activity) {
currentResumedActivity == null
}
override fun onActivityStarted(activity: Activity) {
activityStartCount++
if (activityStartCount == 1) {
listener?.onAppFront()
}
}
override fun onActivityDestroyed(activity: Activity) = Unit
override fun onActivitySaveInstanceState(activity: Activity, bundle: Bundle) = Unit
override fun onActivityStopped(activity: Activity) {
activityStartCount--
if (activityStartCount == 0) {
listener?.onAppBackground()
}
}
override fun onActivityCreated(activity: Activity, bundle: Bundle?) = Unit
override fun onActivityResumed(activity: Activity) {
currentResumedActivity = WeakReference(activity)
}
fun getCurrentActivity(): Activity? {
return currentResumedActivity?.get()
}
}
是不是感覺程式碼有點繁瑣?需要通過對activity記數來判斷應用是否在前後臺。那麼如果我們通過lifecycle會變成怎樣呢?那我們來看一下:
/**
* @date:2021/02/08
* @author:Silence
* @describe:
**/
class AppLifeObserver : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onForeground() {
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun onBackground() {
}
}
然後我們在application直接呼叫如下程式碼:
ProcessLifecycleOwner.get().lifecycle.addObserver(AppLifeObserver())
是不是相對之前的記數方法簡單很多。而且通過lifecycle的實現可讀性相對而言會更高。
總結
本篇我們簡單介紹了lifecycle的使用以及通過嘗試使用lifecycle這個歌簡單的例子對app前臺後做監聽。可以發現lifecycle的使用很簡單。但是本篇並沒有講到lifecycle的原理。因為你只有會使用了才會願意瞭解原理。那麼下一篇我們講lifecycle的實現原理。
參考
本文首發於我的個人部落格:Android Jetpack架構元件——Lifecycle使用篇
更多文章請關注我的公眾號:碼農職場