Jetpack系列(一) -- Lifecycle

本文介绍了如何在AndroidJetpack中使用Lifecycle框架,包括基础知识、不同类型的Observer(如DefaultLifecycleObserver和LifecycleEventObserver)以及如何通过Lifecycle解决Activity中的内存泄漏问题,特别是通过自定义Dialog实现生命周期观察。
摘要由CSDN通过智能技术生成

前言

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

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

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

本篇时间: 23/09/09

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

Gradle版本:

在这里插入图片描述

Lifecycle基本使用

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

  • 被观察者MainActivity

  • 观察者为自定义类 MainLifeObserver

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

  • 添加如下依赖

    implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.1")
    

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

在这里插入图片描述

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

DefaultLifecycleObserver

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

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)方法。

class MainLifeObserver: LifecycleEventObserver {
    val TAG = "MainLifeObserver"

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

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

    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中设置一下。

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就可以了。

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的视图。

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跳转到对应类里去查看,或者直接查阅相关的书本或文章。

代码地址-github

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-情绪零碎-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值