咱们好,本篇文章给咱们分享下官方开源库activity-ktx供给的几个有用的小东西,期望能对你有所协助,本篇文章为咱们带来ComponentDialog的介绍。

当前根据如下版别进行剖析:

dependencies {
    implementation "androidx.activity:activity-ktx:1.8.0"
}

ComponentDialog—集各种特性于一体的大成Dialog

假如经常运用Android Jetpack相关组件的开发者,相信对下面的几个接口非常了解:

  • LifecycleOwner:供给组件可观察的生命周期
  • OnBackPressedDispatcherOwner:供给体系回来按钮事情的监听;
  • SavedStateRegistryOwner:保存因装备发生更改界面毁掉重建前的相关数据,重建后可以重新获取

凭借于官方的支持,上面这些接口特性在ActivityFragment中都有表现,但是咱们想一想,Dialog有这个待遇吗?哈哈,这不ComponentDialog组件就应运而生了。

open class ComponentDialog @JvmOverloads constructor(
    context: Context,
    @StyleRes themeResId: Int = 0
) : Dialog(context, themeResId),
    LifecycleOwner,
    OnBackPressedDispatcherOwner,
    SavedStateRegistryOwner {
        //...
}

ComponentDialog实现了上面的三个接口,所以具有了三个接口对应的才能,接下来咱们来分别演示下。

先自定义一个ComponentDialog类:

class CustomComponentDialog(mContext: Context): ComponentDialog(mContext) {
    override fun onSaveInstanceState(): Bundle {
        return super.onSaveInstanceState()
    }
}

1. LifecycleOwner才能

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val customComponentDialog = CustomComponentDialog(this)
        customComponentDialog.show()
        customComponentDialog.lifecycle.addObserver(object : DefaultLifecycleObserver {
            override fun onCreate(owner: LifecycleOwner) {
                super.onCreate(owner)
            }
            override fun onResume(owner: LifecycleOwner) {
                super.onResume(owner)
            }
            override fun onDestroy(owner: LifecycleOwner) {
                super.onDestroy(owner)
            }
        })
    }

假如是咱们直接之前运用Dialog,为了监听Dialog的show和dismiss等场景,都会自动调用办法比方setOnDismissListenersetOnShowListener等设置监听器,这样就会导致一个安全隐患:Dialog持有了外部类引证,而这个外部类引证会被对象池中的Message持有,假如这个Message和HanderThread音讯队列中的Message同享,那这就发生内存走漏的安全隐患。DialogFragment也相同存在这样的安全隐患。

这个内存走漏的安全隐患就不再这儿进行剖析了,咱们可以这两篇文章了解学习一番:

Android开发:Message 引发的 DialogFragment 内存走漏剖析与解决方案

运用Dialog可能引起的内存走漏

而现在ComponentDialog供给了Lifecycle的才能,咱们就可以通过增加观察者的办法来监听Dialog的show和dismiss,而不会发生一点点内存走漏的安全隐患,咱们可以定心食用。

不过这儿有两点需求注意的当地:

  1. lifecycle的resume办法执行是早于监听器setOnShowListener(DialogInterface.OnShowListener)回调时机,其凭借ComponentDialog#onStart()办法告诉观察者Resume事情发生

    ComponentDialog—集各种特性于一体的大成Dialog
  2. lifecycle的destory办法执行相同早于监听器setOnDismissListener(DialogInterface#OnDismissListener)回调时机,其凭借ComponentDialog#onStop告诉观察者onDestory事情发生

    ComponentDialog—集各种特性于一体的大成Dialog

2. OnBackPressedDispatcherOwner才能

供给监听体系回来按键点击事情的才能

customComponentDialog.onBackPressedDispatcher.addCallback {
    Log.i("TAG", "onCreate: onBackPressedDispatcher")
    isEnable = false
}

不过这个东西可要善用,比方假如上面代码中没有关键的isEnable = false,那么相当于体系回来按钮事情就被这个Dialog给拦截了,其他的当地back事情都无法响应了

所以当处理完Dialog的back监听事情后,需求自动设置isEnable = false才能保证该体系回来键点击事情可以正常流转,当然了详细要视业务场景而定。

详细的使用场景也会有不少,比方当前正在显示一个供给编辑才能的Dialog,先设置个onBack监听,在点击体系回来键时,提示用户是否要保存草稿等相似功能。相比较直接重写onKeyUp、onBackPress等体系办法,设置onBackPressedCallback的办法运用起来愈加灵敏方便。

顺便给咱们推荐一个好用的扩展办法,这样增加onback监听就十分方便了:

ComponentDialog—集各种特性于一体的大成Dialog

3. SavedStateRegistryOwner才能

这个相似于有点相似于ViewModel,可以保存状况数据,比方当界面由于旋转、换肤等此原因导致Activity重建时,就可以将之前的数据进行重现,和ViewModel的才能有点像。

customComponentDialog.savedStateRegistry.registerSavedStateProvider("key") {
    Bundle().apply { 
        putInt("count", 100)
    }
}

指定一个key,以及要存储的数据即可,终究这个伴随着Dialog#onSaveInstanceState()一同存储。

不过这个效果感觉运用场景不大,并且存在运用约束,并且Dialog依赖Activity的context,直接运用Activity的ViewModel保存数据也能实现Dialog状况数据的保存以及恢复。

当然了仁者见仁,智者见智,对于Dialog运用的这个特性再这儿就不再提了。

历史文章

一文洞彻:Application为啥不能作为Dialog的context?

这篇文章咱们可以看看哈,也是运用Dialog时需求了解的一个知识点,带你了解Dialog的context一定不能是Application吗?只能是Activity吗?

子线程刷UI->Barrier屏障->主线程装死->使用GG?太难了