Lifecycle解决Dialog内存泄漏的问题

语言: CN / TW / HK

highlight: a11y-dark theme: condensed-night-purple


持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情

Dialog是安卓开发中常用的组件之一,但是它的使用过程中会出现一个问题。当我们activity关闭时,若Dialog没有关闭会导致内存泄漏。内存泄漏其实比较好处理,只需要当activity关闭时销毁Dialog就行。但是如果关闭销毁Dialog的逻辑可能比较复杂,而利用Jetpack中的Lifecycle可以比较完美的解决Dialog内存泄漏的问题。

Lifecycle是什么?

Lifecycle是Jetpack用来感知生命周期的组件,使用Lifecycle可以帮助我们写出与生命周期相关且更简洁,容易后期维护的代码。Lifecycle可以通过在activity注册观察者从而感知到当前页面的生命周期,进而对相应生命周期方法中的逻辑进行抽离。将业务逻辑和activity剥离,使得代码简洁且适合后期维护。

为什么Lifecycle可以用来监听Dialog的生命周期:

因为Dialog都是需要依附于一个activity,这个主要是因为安卓底层绘制原理所决定的。一个窗体(Window)对应一个绘制图层,phoneWindow作为主绘制图层其他的图层需要依附于它,并且渲染时所有窗体的视图数据必须都写进图形缓冲区里面,因此Dialog必须依附于activity。既然Dialog依附于activity,那么就意味着Dialog可以通过Lifecycle去感知acitivity的生命周期,进而对自己的状态进行管理。

Lifecycle怎么写一个不会内存泄漏的Dialog

如下方代码就实现了当Dialog所依附的acitivity销毁时,Dialog也随之关闭,这样内存泄漏的问题就不存在了。

``` class TipDialog(context: Context) Dialog ( context ), LifecycleObserver { init { if (context is componentActivity) { (context as componentActivity).lifecycle.addObserver(this)

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstancestate)
            setContentView(R.layout.item_tip_dialog)

            @OnLifecycleEvent(Lifecycle.Event.ON_DESTRoY) 
            private fun onDestroy() {
                if (isShowing) {
                    dismiss()
                }
            }
        }

```

由于在实际使用中Dialog可能不仅仅存在内存泄漏的问题,所以需要开发者根据实际情况在Activity的生命周期方法中做处理。

感谢您的阅读,专注才能提高学习效率,peace!