DialogFragment的dismiss()与getDialog().dismiss()的区别及使用建议
DialogFragment 两种关闭方式的差异与选型
优先选型结论
优先使用第一种实现,即直接调用DialogFragment自身的dismiss()方法:
public void dismissDialog(MyDialog dialog){ dialog.dismiss(); }
第二种实现属于非常规用法,存在大量隐患,非特殊场景不推荐使用。
两种方式的核心差异
MyDialog继承自DialogFragment,两种调用的本质操作对象完全不同:第一种调用的是DialogFragment封装的方法,第二种调用的是DialogFragment内部包裹的原生Dialog对象的方法,具体差异体现在以下几点:
- 空指针风险差异
getDialog()只有在DialogFragment执行完onCreateDialog()生命周期后才会返回非空实例。如果在DialogFragment初始化阶段、或者已经被销毁的阶段调用getDialog().dismiss(),会直接触发空指针崩溃;而DialogFragment自身的dismiss()内部做了状态校验,无论当前Fragment处于未attach、已移除等任意状态,调用都不会崩溃,最多无实际效果。 - 生命周期与状态一致性差异
直接调用原生Dialog的dismiss(),仅会关闭弹窗的视图展示,不会触发DialogFragment对应的Fragment事务移除流程,也不会执行onDestroyView()、onDestroy()等Fragment生命周期,更不会将当前DialogFragment实例从FragmentManager的回退栈中移除。
这会衍生出一系列问题:比如屏幕旋转等配置变更时,残留的DialogFragment实例会被系统自动重建,重新弹出已经被手动关闭的弹窗;同时FragmentManager会持有无法回收的残留实例,引发内存泄漏。 - 状态丢失保护差异
DialogFragment自身的dismiss()内部会适配Android的状态保存规则:如果在onSaveInstanceState()之后调用关闭逻辑,会自动走dismissAllowingStateLoss()逻辑,避免触发Activity状态丢失的异常;而直接调用原生Dialog的dismiss()完全没有这层保护。
特殊场景说明
只有当你需要仅临时关闭弹窗视图、但要保留DialogFragment的实例状态用于后续恢复时,才可以操作内部Dialog对象。但即便这种场景,也更推荐使用dialog.getDialog().hide()而非dismiss(),避免不必要的视图销毁逻辑。
内容的提问来源于stack exchange,提问作者fatihberatcan
相关产品推荐
相关产品推荐

