1. 程式人生 > 其它 >Android Jetpack架構元件——Lifecycle使用篇

Android Jetpack架構元件——Lifecycle使用篇

技術標籤:Jetpackandroid

概述

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使用篇
更多文章請關注我的公眾號:碼農職場
在這裡插入圖片描述