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

相关推荐
帅次1 小时前
Android CoordinatorLayout:打造高效交互界面的利器
android·gradle·android studio·rxjava·android jetpack·androidx·appcompat
夏非夏2 天前
Kotlin jetpack MVP
android·kotlin
zhangphil2 天前
Kotlin约束泛型参数必须继承自某个父类
kotlin
ch_kexin2 天前
Android kotlin integer-array 存放图片资源ID
android·开发语言·kotlin
IAM四十二2 天前
Jetpack Compose State 你用对了吗?
android·android jetpack·composer
jiay23 天前
Kotlin-面向对象之构造函数、实例化和初始化
android·开发语言·kotlin
我怀里的猫3 天前
glide ModelLoader的Key错误使用 可能造成的内存泄漏
android·kotlin·glide
陟彼高冈yu3 天前
第10天:Fragments(碎片)使用-补充材料——‘MainActivity.kt‘解读
android·kotlin·android studio
姑苏风3 天前
《Kotlin实战》-第11章:DSL构建
android·开发语言·kotlin
Wgllss3 天前
那些大厂架构师是怎样封装网络请求的?
android·架构·android jetpack