来自《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)
}
}
相信很多开发者都遇到过这个错误,这是因为在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可以感应生命周期变化,示例如下:
上面的代码在2.2.1节中已经详细介绍了,此处就不再赘述。当Dialog所依附的Activity被销毁时,Dialog也可以自动关闭,再也不用担心Dialog的内存泄漏问题了。如此一来,就使用Lifecycle实现了一个完美的Dialog。
来自《Android Jetpack开发:原理解析与应用实战》的片段,仅作备注,如果侵权,请联系删除。