Jetpack系列(一) -- Lifecycle

前言

选读书籍--《Android Jetpack开发 原理解析与应用实战》------ 著: 黄林晴

这系列主要为是初步学习jetpack开发所写,不仅是加深映像,也希望给自己更多的启发。

这个系列一周会至少发布一篇(工作原因),读者也可以来监督我(可享私信催更)。

本篇时间: 23/09/09

AndroidStudio版本: Giraffe 2022.3.1 JDK:17 开发语言: Kotlin

Gradle版本:

Lifecycle基本使用

在大佬黄林晴的书本中,lifecycle使用初始结构如下(与书籍不同,理解就行):

  • 被观察者MainActivity

  • 观察者为自定义类 MainLifeObserver

  • MainActivityObserver实现LifecycleObserver,给需要客制化的方法添加@OnLifecycleEvent注释

  • 添加如下依赖

    groovy 复制代码
    implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.1")

但是在最近的版本Google要求废弃@OnLifecycleEvent的使用,如图

意思是这个注释会使用代码生成或反射,增加工作量,应当避免使用。并且给了两个推荐方法------DefaultLifecycleObserverLifecycleEventObserver

DefaultLifecycleObserver

使用方法,观察者自定义类 MainLifeObserver实现DefaultLifecycleObserver接口,重写你需要观察的Activity的生命周期方法。如下:

kotlin 复制代码
class MainLifeObserver: DefaultLifecycleObserver {
    val TAG = "MainLifeObserver"

    override fun onCreate(owner: LifecycleOwner) {
        super.onCreate(owner)
        Log.d(TAG, "onCreate: ")
    }

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

LifecycleEventObserver

使用方法,观察者自定义类 MainLifeObserver实现LifecycleEventObserver接口,并重写onStateChanged(LifecycleOwner, Lifecycle.Event)方法。

kotlin 复制代码
class MainLifeObserver: LifecycleEventObserver {
    val TAG = "MainLifeObserver"

    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        Log.d(TAG, "onStateChanged: event --> $event")
    }
}

Lifecycle.Event对应的就是Activity的生命周期枚举类

kotlin 复制代码
    public enum class Event {
        /**
         * Constant for onCreate event of the [LifecycleOwner].
         */
        ON_CREATE,

        /**
         * Constant for onStart event of the [LifecycleOwner].
         */
        ON_START,

        /**
         * Constant for onResume event of the [LifecycleOwner].
         */
        ON_RESUME,

        /**
         * Constant for onPause event of the [LifecycleOwner].
         */
        ON_PAUSE,

        /**
         * Constant for onStop event of the [LifecycleOwner].
         */
        ON_STOP,

        /**
         * Constant for onDestroy event of the [LifecycleOwner].
         */
        ON_DESTROY,

        /**
         * An [Event] constant that can be used to match all events.
         */
        ON_ANY;
    }

MainActivity

当然这样还不行,因为被观察者还没有绑定上观察者,我们需要在MainActivity中设置一下。

kotlin 复制代码
class MainActivity : Activity(), LifecycleOwner {

    lateinit var binding: ActivityMainBinding

    private val lifecycleRegistry = LifecycleRegistry(this@MainActivity)

    override val lifecycle: Lifecycle
        get() = lifecycleRegistry

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        val myLifecycleObserver = MainLifeObserver()
        lifecycle.addObserver(myLifecycleObserver)
    }

}

这个是MainActivity继承于android.app.Activity的时候,我们需要实现LifecycleOwner接口,并重写getLifecycle()方法。这个时候我们就要用到 Lifecycle 的唯一实现类LifecycleRegistry。实例化之后直接给到getLifecycle()。

当然目前大部分情况下,不管是AS生成还是Google建议,Activity都是继承于AppCompatActivity的,而AppCompatActivity继承于ComponentActivity,ComponentActivity已经实现了LifecycleOwner接口方法。我们直接调用lifecycle就可以了。

kotlin 复制代码
class MainActivity : AppCompatActivity(){

    lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        val myLifecycleObserver = MainLifeObserver()
        lifecycle.addObserver(myLifecycleObserver)
    }

}

Log输出

LifecycleEventObserver为例子

使用lifecycle解决内存泄漏问题

在我们编写代码的过程中,总会依附于Activity来完成一些其它刚需。例如ToastDialog,当然也不至于此。但是我们在使用上述两个工具时,会调用到Activity本身的Context。对内存泄漏有初步了解的话,应该知道Context在强引用(直接调用)的时候就有可能会产生内存泄漏,因为它不会在Activity关闭后回收内存。

那这个时候,我们就可以自定义Toast或者Dialog来实现LifecycleObserver(这里不是指具体类,而是泛指lifecycle的观察者),观察Activity的生命周期,当Activity关闭时,我们就可以同步关闭引用了Context的视图。

kotlin 复制代码
class MainActivity : AppCompatActivity(){

    lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        val dialog = AutoDialog(this)
      //  val myLifecycleObserver = MainLifeObserver()
        lifecycle.addObserver(dialog)
        binding.show.setOnClickListener {
            dialog.show()
        }
    }

    class AutoDialog(context: Context) : Dialog(context), LifecycleEventObserver{
        private val TAG = "Dialog"
        override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
            when (event) {
                Lifecycle.Event.ON_DESTROY ->
                    if (isShowing) {
                        Log.d(TAG, "onStateChanged: ")
                        dismiss()
                    }
                else -> {}
            }
        }

    }

}

我这里选择直接在Activity类里添加了一个内部类,但实际情况并不建议这样使用,或者说是不能这么用。因为不管是mvc,mvp还是mvvm都是致力于减轻Activity的代码和解耦view和model,这样反而是反方向发展。在实际情况中建议另开一个类,包括可以自定义视图,不仅Activity中看着简洁,而且还能对这个Dialog进行复用。

疑问

可能大家会问,你这样子操作不就是在Activity执行Destory的时候手动dismiss Dialog一样的效果吗?

没错,效果是一样的,但是使用lifecycle有他的用意,借用黄林晴大佬的原话:

虽然上面的方法(直接在onDestory中dismiss)可以解决内存泄漏问题,但若弹窗类型很多,则需要在onDestory中编写许多额外的处理逻辑,且容易忘记。

不明觉厉,如果我们在实际使用时,用到的像Dialog这种很多,我们为了不让内存泄漏,会在onDestory中写很多代码,不仅不优雅,而且不优雅。

总结

初步认识Lifecycle的使用,也了解了Android使用Lifecycle的重要性。

关于Lifecycle的原理,例如ComponentActivity里是如何实现的Lifecycle,这些东西就不做细究,感兴趣可以自己编写代码通过AS跳转到对应类里去查看,或者直接查阅相关的书本或文章。

demo地址-github

相关推荐
JMchen12316 小时前
Jetpack 内核实战(九):实战(上)——记事本首页列表 + 搜索功能开发
kotlin·android 实战·记事本 app 开发·recyclerview 优化·jetpack 综合实战
pengyu18 小时前
【Kotlin 协程修仙录 · 炼虚境 · 初阶】 | 虚空造物:Channel 基础与协程间通信的管道艺术
android·前端·kotlin
小强闯江湖18 小时前
ViewCompose:让原生 Android View 进入声明式时代
android·开源·kotlin
我命由我1234521 小时前
人脸识别 - 判断人脸是否在画面中央
java·人工智能·python·java-ee·人脸识别·android jetpack·android runtime
雨白1 天前
Kotlin 委托机制:搞懂“老板与秘书”模式
kotlin
pengyu2 天前
【Kotlin 协程修仙录 · 化神境 · 后阶】 | 异常天劫:Flow 异常处理的终极奥义与重试之道
android·kotlin
pengyu2 天前
【Kotlin 协程修仙录 · 化神境 · 中阶】 | 多播奥义:SharedFlow 高级配置与 Channel 的抉择之道
android·kotlin
撩得Android一次心动2 天前
Kotlin 语言【知识点整理2】
android·开发语言·kotlin
一个用户名i3 天前
【Compose 系列】第 4 篇:布局与 Modifier,写界面不走弯路
android jetpack
一个用户名i3 天前
【Compose 系列】第 3 篇:状态管理入门,让界面「动」起来
android jetpack