Android Jitpack 组件之 Lifecycle(Kotlin)

一、导入 Library

在 build.gradle 中导入库:

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.lifecycle:lifecycle-common-java8:2.2.0'

添加 Java 和 Kotlin 的 java8 支持:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
    jvmTarget = '1.8'
}

二、监听 Activity 生命周期

监听生命周期有两种方式,一是继承 DefaultLifecycleObserver,在其重载方法中处理。二是使用注解,在方法上添加生命周期回调事件的注解,就能接收到对应回调。
Google 官方推荐使用方式一,因为随着 Java8 的流行,注解可能会被废弃。

方式一:继承 DefaultLifecycleObserver

新建 MyLifecycleObserver 类,继承自 DefaultLifecycleObserver

class MyLifecycleObserver : DefaultLifecycleObserver{
    override fun onCreate(owner: LifecycleOwner) {
        super.onCreate(owner)
        Log.d("~~~", "onCreate")
    }

    override fun onResume(owner: LifecycleOwner) {
        super.onResume(owner)
        Log.d("~~~", "onResume")
    }

    override fun onPause(owner: LifecycleOwner) {
        super.onPause(owner)
        Log.d("~~~", "onPause")
    }

    override fun onStart(owner: LifecycleOwner) {
        super.onStart(owner)
        Log.d("~~~", "onStart")
    }

    override fun onStop(owner: LifecycleOwner) {
        super.onStop(owner)
        Log.d("~~~", "onStop")
    }

    override fun onDestroy(owner: LifecycleOwner) {
        super.onDestroy(owner)
        Log.d("~~~", "onDestroy")
    }
}

在需要监听生命周期的 Activity 中,给 lifecycle 添加此观察者:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        lifecycle.addObserver(MyLifecycleObserver())
    }
}

大功告成,现在这个 activity 的生命周期回调触发时,MyLifecycleObserver 的对应方法就能监听到了。

方式二:使用注解

新建 MyLifecycleObserver 类,让其继承自 LifecycleObserver。通过给方法添加 OnLifecycleEvent 注解的方式监听生命周期。

class MyLifecycleObserver : LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun create() {
        Log.d("~~~", "ON_CREATE")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun start() {
        Log.d("~~~", "ON_START")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun resume() {
        Log.d("~~~", "ON_RESUME")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun pause() {
        Log.d("~~~", "ON_PAUSE")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun stop() {
        Log.d("~~~", "ON_STOP")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun destroy() {
        Log.d("~~~", "ON_DESTROY")
    }
}

在需要监听生命周期的 Activity 中,给 lifecycle 添加此观察者:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        lifecycle.addObserver(MyLifecycleObserver())
    }
}

两种方式的效果是一样的。

三、Lifecycle 的状态

3.1.五种状态

Lifecycle 一共有五种状态,分别是:

  • INITIALIZED
  • CREATED
  • STARTED
  • RESUMED
  • DESTROYED

官网上用一张图表示了 Lifecycle 的状态与生命周期的关系:

3.2.状态改变的时机

我们修改一下 MainActivity,来测一下 Lifecycle 的几种状态改变的时机。

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        Log.d("~~~", "OnCreate start, ${lifecycle.currentState}")
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        lifecycle.addObserver(MyLifecycleObserver())
        Log.d("~~~", "OnCreate end, ${lifecycle.currentState}")
    }

    override fun onStart() {
        Log.d("~~~", "onStart start, ${lifecycle.currentState}")
        super.onStart()
        Log.d("~~~", "onStart end, ${lifecycle.currentState}")
    }

    override fun onResume() {
        Log.d("~~~", "onResume start, ${lifecycle.currentState}")
        super.onResume()
        Log.d("~~~", "onResume end, ${lifecycle.currentState}")
        Thread(Runnable {
            Thread.sleep(1000)
            Log.d("~~~", "waiting 1 second after onResume, ${lifecycle.currentState}")
        }).start()
    }

    override fun onPause() {
        Log.d("~~~", "onPause start, ${lifecycle.currentState}")
        super.onPause()
        Log.d("~~~", "onPause end, ${lifecycle.currentState}")
    }

    override fun onStop() {
        Log.d("~~~", "onStop start, ${lifecycle.currentState}")
        super.onStop()
        Log.d("~~~", "onStop end, ${lifecycle.currentState}")
    }

    override fun onDestroy() {
        Log.d("~~~", "onDestroy start, ${lifecycle.currentState}")
        super.onDestroy()
        Log.d("~~~", "onDestroy end, ${lifecycle.currentState}")
    }
}

运行程序,程序打开后,等待 1 秒多的时间(等待 1 秒是为了便于观察 RESUMED 状态),点击返回键退出。Log 输出如下:

2020-03-03 22:29:39.569 20742-20742/com.example.myapplication D/~~~: OnCreate start, currentState is INITIALIZED
2020-03-03 22:29:39.747 20742-20742/com.example.myapplication D/~~~: OnCreate end, currentState is INITIALIZED
2020-03-03 22:29:39.750 20742-20742/com.example.myapplication D/~~~: ON_CREATE
2020-03-03 22:29:39.754 20742-20742/com.example.myapplication D/~~~: onStart start, currentState is CREATED
2020-03-03 22:29:39.758 20742-20742/com.example.myapplication D/~~~: onStart end, currentState is CREATED
2020-03-03 22:29:39.758 20742-20742/com.example.myapplication D/~~~: ON_START
2020-03-03 22:29:39.759 20742-20742/com.example.myapplication D/~~~: onResume start, currentState is STARTED
2020-03-03 22:29:39.759 20742-20742/com.example.myapplication D/~~~: onResume end, currentState is STARTED
2020-03-03 22:29:39.760 20742-20742/com.example.myapplication D/~~~: ON_RESUME
2020-03-03 22:29:40.761 20742-20794/com.example.myapplication D/~~~: waiting 1 second after onResume, currentState is RESUMED
2020-03-03 22:29:48.028 20742-20742/com.example.myapplication D/~~~: ON_PAUSE
2020-03-03 22:29:48.028 20742-20742/com.example.myapplication D/~~~: onPause start, currentState is STARTED
2020-03-03 22:29:48.029 20742-20742/com.example.myapplication D/~~~: onPause end, currentState is STARTED
2020-03-03 22:29:48.655 20742-20742/com.example.myapplication D/~~~: ON_STOP
2020-03-03 22:29:48.655 20742-20742/com.example.myapplication D/~~~: onStop start, currentState is CREATED
2020-03-03 22:29:48.656 20742-20742/com.example.myapplication D/~~~: onStop end, currentState is CREATED
2020-03-03 22:29:48.660 20742-20742/com.example.myapplication D/~~~: ON_DESTROY
2020-03-03 22:29:48.660 20742-20742/com.example.myapplication D/~~~: onDestroy start, currentState is DESTROYED
2020-03-03 22:29:48.661 20742-20742/com.example.myapplication D/~~~: onDestroy end, currentState is DESTROYED

经过测试,我们发现打开 app 时:

  • Lifecycle 在 Activity 的 onCreate 方法中,状态一直是 INITIALIZED。Activity 的 onCreate 执行完后,才会回调 Observer 的 onCreate 方法,然后状态变成 CREATED
  • Lifecycle 在 Activity 的 onStart 方法中,状态一直是 CREATED。Activity 的 onStart 执行完后,才会回调 Observer 的 onStart 方法,然后状态变成 STARTED
  • Lifecycle 在 Activity 的 onResume 方法中,状态一直是 STARTED。Activity 的 onResume 执行完后,才会回调 Observer 的 onResume 方法,然后状态变成 RESUMED

关闭 app 时:

  • Activity 的 onPause 执行前,先回调 Lifecycle 的 onPause 方法,Lifecycle 状态变为 STARTED。然后再去执行 Activity 的 onPause 方法,在 Activity 的 onPause 方法中,Lifecycle 的状态一直是 STARTED
  • Activity 的 onStop 执行前,先回调 Lifecycle 的 onStop 方法,Lifecycle 状态变为 CREATED。然后再去执行 Activity 的 onStop 方法,在 Activity 的 onStop 方法中,Lifecycle 的状态一直是 CREATED
  • Activity 的 onDestroy 执行前,先回调 Lifecycle 的 onDestroy 方法,Lifecycle 状态变为 DESTROYED。然后再去执行 Activity 的 onDestroy 方法,在 Activity 的 onDestroy 方法中,Lifecycle 的状态一直是 DESTROYED

总结起来就是:进入时最后改 Lifecycle 状态,退出时最先改 Lifecycle 状态。

3.3.active 与 inactive 的 Lifecycle

当 Lifecycle 处于 STARTED 或 RESUMED 状态时,我们认为 Lifecycle 是 active 的,否则认为是 inactive 的。

四、监听 Application 生命周期

监听整个 app 的生命周期,官方文档推荐使用 ProcessLifecycleOwner。
同样可以使用继承或注解两种方式。MyLifecycleObserver 类和上述代码一模一样。在 Application 中,使用 ProcessLifecycleOwner 添加此观察者:

class MyApplication : Application(), LifecycleObserver {
    override fun onCreate() {
        super.onCreate()
        ProcessLifecycleOwner.get().lifecycle.addObserver(MyLifecycleObserver())
    }
}

当 app 启动时,依次回调 onCreate、onStart、onResume,当 app 退出时,依次回调 onPause、onStop,并且永远不会回调 onDestroy。官方文档中提到,onPause、onStop 回调是有一定间隔的,目的是保证在手机旋转等配置改变时引起的 Activity 销毁和重建时不发送 Event。查看源码可以发现,这个间隔时间是 700ms。并且源码中是通过监听前台 Activity 的数量实现的此功能。我们也可以通过这种方式来监听 app 前后台切换。

注:笔者在 mac 的安卓模拟器上使用 ProcessLifecycleOwner 没有监听到 onPause、onStop 回调,但 Windows 的模拟器上可以监听到,暂不清楚原因。

五、监听 app 前后台切换

新建 MyActivityLifecycleCallbacks 单例:

object MyActivityLifecycleCallbacks : Application.ActivityLifecycleCallbacks {
    private var foregroundActivityCounts = 0

    override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
    }

    override fun onActivityStarted(activity: Activity) {
        if (foregroundActivityCounts++ == 0) {
            Log.d("~~~", "foreground")
        }
    }

    override fun onActivityResumed(activity: Activity) {
    }

    override fun onActivityPaused(activity: Activity) {
    }

    override fun onActivityStopped(activity: Activity) {
        if (--foregroundActivityCounts == 0) {
            Log.d("~~~", "background")
        }
    }

    override fun onActivityDestroyed(activity: Activity) {
    }

    override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
    }

    fun isAppForeground(): Boolean {
        return foregroundActivityCounts > 0
    }

}

在 Application 中注册此 LifecycleCallbacks

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        registerActivityLifecycleCallbacks(MyActivityLifecycleCallbacks)
    }
}

在 MyActivityLifecycleCallbacks 中,我们维护了一个 int 变量 foregroundActivityCounts ,用来记录此 app 前台 Activity 的数量。
每当 Activity 的 onStart 回调时,foregroundActivityCounts++,每当 Activity 的 onStop 回调时,–foregroundActivityCounts。

如果 foregroundActivityCounts 从 0 变成 1,说明 app 进入前台,如果 foregroundActivityCounts 从 1 变成 0,说明 app 进入后台。

MyActivityLifecycleCallbacks 声明了 isAppForeground 方法,通过 foregroundActivityCounts 是否大于 0 来判断 app 是否在前台。

六、总结

在应用开发中,我们常常会有一些逻辑需要与生命周期绑定。比如:页面展示在前台时播放视频,切换到后台时暂停播放。应用开始时初始化,应用退出时释放资源。通过本文介绍的这些监听方法,可以让这些代码逻辑自己处理生命周期,实现更好的解耦。

伪代码表示如下,使用 Lifecycle 前:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        LibraryA.init()
        LibraryB.init()
        LibraryC.init()
    }

    override fun onResume() {
        super.onResume()
        LibraryA.resume()
        LibraryB.resume()
        LibraryC.resume()
    }

    override fun onPause() {
        super.onPause()
        LibraryA.pause()
        LibraryB.pause()
        LibraryC.pause()
    }

    override fun onDestroy() {
        super.onDestroy()
        LibraryA.release()
        LibraryB.release()
        LibraryC.release()
    }
}

使用 Lifecycle 后:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        lifecycle.addObserver(LifecycleObserverA())
        lifecycle.addObserver(LifecycleObserverB())
        lifecycle.addObserver(LifecycleObserverC())
    }
}
原创文章 67 获赞 68 访问量 6万+

猜你喜欢

转载自blog.csdn.net/AlpinistWang/article/details/104602741