使用Lifecycle解决Dialog内存泄漏问题

321 阅读2分钟

来自《Android Jetpack开发:原理解析与应用实战》的片段,仅作备注,如果侵权,请联系删除。

2.3 使用Lifecycle解决实际项目中常见的问题

了解Lifecycle的基本使用之后,接着来看如何使用Lifecycle解决实际项目中常见的问题。

2.3.1 Dialog内存泄漏问题分析 Dialog是Android开发中最常用的组件之一,相信每位读者都使用过。现在一起实现一个Dialog,用于网络请求的简单提示。Dialog的代码很简单,直接设置一个布局即可,具体如下:

class TipDialog(context: Context) : Dialog(context) { 
override fun onCreate(savedInstanceState: Bundle?) { 
        super.onCreate(savedInstanceState) 
        setContentView(R.layout.item_tip_dialog) 
    } 
}

接下来模拟如下场景:

■进入页面时开始网络请求,显示Dialog。

■请求结束时(两秒后),退出当前页面。下面实现上述需求,Activity的代码如下:

class MainActivity : AppCompatActivity() { 
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState) 
        setContentView(R.layout.activity_main2) 
        TipDialog(this).show() Handler().postDelayed({
            finish() 
        }, 2000) 
    } 
}

image.png 相信很多开发者都遇到过这个错误,这是因为在Activity关闭的时候,Dialog没有关闭,进而导致内存泄漏。了解了出现异常的原因,解决起来就很容易了,在销毁Activity的时候,关闭Dialog即可,示例代码如下:

class MainActivity : AppCompatActivity() {
    var dialog: TipDialog? = null 
    override fun onCreate(savedInstanceState: Bundle?) { 
        super.onCreate(savedInstanceState) 
        setContentView(R.layout.activity_main2) 
        dialog = TipDialog(this) dialog?.show() 
        Handler().postDelayed({ 
            finish()
        }, 2000) 
    } 

    override fun onDestroy() { 
        super.onDestroy() 
        dialog?.dismiss() 
    } 
}

上面的方法虽然可以解决内存泄漏问题,但若弹窗类型很多,则需要在onDestroy中编写许多额外的处理逻辑,且容易忘记,不过,如果使用Lifecycle组件,就可以完美地解决这个问题。

2.3.2 使用Lifecycle打造一个完美的Dialog

由于Dialog中的参数Context必须是Activity的上下文,因此开发者完全可以在Dialog中使用Lifecycle组件来感知生命周期,在2.2.1节中已经介绍,只要是在androidx.fragment.app.Fragment、ComponentActivity及其子类Activity中,就可以直接使用Lifecycle组件。所以这成了一个取舍问题,如果xxxActivity继承的是Activity,将无法直接使用Lifecycle,那就只能自定义LifecycleOwner或者在Activity中注册了,但是这样做完全没有必要,这里默认xxxActivity继承的是ComponentActivity。

修改TipDialog的代码,使得TipDialog可以感应生命周期变化,示例如下:

image.png 上面的代码在2.2.1节中已经详细介绍了,此处就不再赘述。当Dialog所依附的Activity被销毁时,Dialog也可以自动关闭,再也不用担心Dialog的内存泄漏问题了。如此一来,就使用Lifecycle实现了一个完美的Dialog。

来自《Android Jetpack开发:原理解析与应用实战》的片段,仅作备注,如果侵权,请联系删除。