Android lifecycle的使用

1. 簡介

爲了應用的安全,常常會有從後臺切回前臺時進行軟件確認等安全確認處理的需求。若是是之前的話,這個需求實際上是挺難實現的。 但自從Google推出Lifecycle組件之後,這個需求就簡單了不少。Lifecycle除了感知從後臺切回前臺之外, 利用這個組件能夠更簡單的實現複雜的處理生命週期的操做。這篇只講述如何實現感知從後臺切回前臺時的生命週期。java

2. Lifecycle組件

2.1 介紹

Lifecycle組件能夠感知Activity和Fragment的生命週期。react

  • 該組件的實現方式是觀察者模式。在生命週期擁有者生命週期的觀察者之間創建觀察與被觀察的關係。當生命週期擁有者的生命週期發生變化時會通知觀察者生命週期觀察者,觀察者收到通知後會進行各類處理。
  • 能夠方便獲取生命週期擁有者的生命週期。

生命週期使用兩個主要枚舉來跟蹤相關組件的生命週期:android

  1. Event : 從框架和LifeCycle類派發的生命週期事件。這些事件映射到Activity和Fragment中的回調事件。
  2. State : 有LifeCycle對象跟蹤的組件的當前狀態。

evernotecid://BF69E971-D524-44B7-91DB-A61998A9A576/appyinxiangcom/18475009/ENResource/p1942 git

2.2 使用場景

  • 能夠集中處理生命週期事件,不用反覆在不一樣的Activity中寫生命週期事件(如解除廣播)。
  • 能夠實現感知整個應用的生命週期。

3. LifeCycle的使用

3.1 添加到依賴庫

根據本身的須要添加LifeCycle的依賴到本身的項目中。github

// ViewModel and LiveData
    implementation "android.arch.lifecycle:extensions:$lifecycle_version"
    // alternatively - just ViewModel
    implementation "android.arch.lifecycle:viewmodel:$lifecycle_version" // use -ktx for Kotlin
    // alternatively - just LiveData
    implementation "android.arch.lifecycle:livedata:$lifecycle_version"
    // alternatively - Lifecycles only (no ViewModel or LiveData).
    // Support library depends on this lightweight import
    implementation "android.arch.lifecycle:runtime:$lifecycle_version"
    annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version"
    // alternately - if using Java8, use the following instead of compiler
    implementation "android.arch.lifecycle:common-java8:$lifecycle_version"
    // optional - ReactiveStreams support for LiveData
    implementation "android.arch.lifecycle:reactivestreams:$lifecycle_version"
複製代碼

3.2 LifeCyleOwner

LifeCycleOwner生命週期的觀察者。會根據收到的通知進行相應處理。LifeCycleOwner的接口很簡單,以下:安全

public Lifecycle getLifecycle() {
    return mLifecycleRegistry;
}
複製代碼

在Activity和Fragment中添加生命週期的觀察者。app

lifecycle.addObserver(AppLifecycleObserver(object:AppLifecycleCallback(){
    // Do something
}))
複製代碼

3.3 LifeCycleObserver

LifeCyclObserver生命週期的被觀察者。在這裏須要定義咱們在生命週期的各個階段中進行的操做。咱們須要經過LifeCycle的註解來標註該方法是在哪一個生命週期被調用。以下:框架

class AppLifecycleObserver : LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onStart() {
        // Do something
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onStop() {
        // Do something
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun onCreate() {
        // Do something
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun onPause() {
        // Do something
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun onDestroy() {
        // Do something
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun onResume() {
        // Do something
    }

    // 全部的生命週期都會調用這個方法
    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    fun onAny() {
        // Do something
    }
}
複製代碼

@OnLifecycleEvent(Lifecycle.Event.ON_ANY)的註解如其名,會在全部的生命週期階段都會被調用。ide

4. 應用切換先後臺的生命週期感知

4.1 實現LifeCyCleObserver類

首先咱們要實現當感知到切回前臺時的操做,因此須要實現的處理寫入到LifeCycleObserver中。 在這裏咱們加入了回調,這些回調將會在Application類中實現。gradle

class AppLifecycleObserver(val callback: AppLifecycleCallback) : LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onStart() {
        callback.onStart()
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun onPause() {
        callback.onPause()
    }
}
複製代碼

固然還有建立回調類。

interface AppLifecycleCallback {

    fun onStart()

    fun onPause()
    
}
複製代碼

4.2 LifeCycleOwner

接下來是在Android中實現LifeCycleOwner類。還有要設置一個Flag,用於記錄先後臺的切狀態。
在這裏說明一下, 爲何會在onStart中進行onForeground操做緣由,而不是onResume。 由於從後臺切回前臺時,都是先調用Activity的生命週期,而後再調用Android的。即Acitivty的OnResume() -> Application的onResume()。這種狀況若是咱們在Application的onResume中進行onForeground操做,Activity會拿到onBackground的flag。 因此若是想在Activity的onResume中判斷切回前臺的狀態,則須要在Application中比onResume狀態以前的狀態中實現。

ProcessLifecycleOwner.get().lifecycle.addObserver(AppLifecycleObserver(object :
            AppLifecycleCallback {
            override fun onStart() {
                onForeground()
                Log.d(TAG, "onStart")
            }

            override fun onPause() {
                onBackground()
                Log.d(TAG, "onPause")
            }
        }))

    }

    fun getAppStatus(): Boolean {
        return isAppActive
    }

    fun onBackground() {
        isAppActive = false
    }

    fun onForeground() {
        isAppActive = true
    }
複製代碼

Application中只能經過ProcessLifecycleOwner中得到lifecycle

4.3 在具體的Acitivty中獲取Flag

雖然能夠在Android實現感知的具體操做, 但實際需求是不須要全部的Activity都須要感知。這個時候能夠在Activity中獲取Flag,根據Flag進行相關處理。

override fun onResume() {
        super.onResume()

        Log.d("MainActivity", "onResume")

        val app = application as AndroidApplication
        Log.d("MainActivity", app.getAppStatus().toString())
        if (app.getAppStatus()) {
            Log.d("MainActivity", "onResume work")
            Toast.makeText(this, "App is in Foreground", Toast.LENGTH_LONG).show()
        }
    }
複製代碼

4.4 實際效果

5. 總結

  • LifeCycleObserver應該避免引用ContextView等, 防止發生內存泄露。應對這個問題可使用回調,即在LifeCycleObserver中加入回調,在Activity和Fragment中實現。
  • 雖然LifeCycle很好用,但不要濫用。 若是項目中不須要大量的生命週期處理,就不須要使用這個組件。

github: github.com/HyejeanMOON…

相關文章
相關標籤/搜索