onCreate中触发BadTokenException崩溃的原因及排查方案问询
问题分析与解决方案
嘿,这个WindowManager$BadTokenException我之前在项目里也踩过坑,咱们来好好捋一捋:
崩溃原因拆解
这个错误本质是:你要显示的ProgressDialog依赖的Activity已经不再处于活跃可交互状态了——对应的窗口令牌(BinderProxy@56492cc)已经失效,系统没办法给一个“已死亡”的Activity添加新窗口(Dialog本质就是一个独立窗口)。
可能的触发场景(即使你无法复现)
虽然你说测试时复现不了,但这种崩溃往往出现在极端或边缘场景:
- 系统内存紧急回收:如果App启动时系统正处于内存极低的状态,Activity在
onCreate执行过程中,可能被系统强制标记为销毁/回收,但你的代码还在继续执行到显示Dialog的逻辑,这时候就会触发令牌无效的错误。 - 用户快速操作:比如用户在Activity刚启动(
onCreate还在执行)时,快速按下返回键,系统会提前标记Activity为finishing状态,但你的代码还在走后续的Dialog显示流程,就会踩坑。 - 配置变更异常:比如屏幕旋转时,如果Activity没有正确处理配置变更,重建过程中也有可能出现这种令牌失效的情况(不过从你的调用栈看,更偏向于前两种场景)。
要不要在onCreate中检查isFinishing()?
必须要!
你之前觉得在onCreate里检查isFinishing()没必要,但实际上即使在onCreate阶段,Activity也有可能已经被标记为finish状态(比如上面提到的两种场景)。在调用ProgressDialog.show()之前加上判断,能直接规避这个崩溃:
if (!isFinishing()) { ProgressDialog.show(this, ...); }
额外优化建议
如果想从根源避免这类问题,推荐用DialogFragment代替原生的ProgressDialog:
DialogFragment会自动感知Activity的生命周期,当Activity销毁时,它会自动关闭Dialog,不会出现令牌无效的问题。- 它也更符合Android Jetpack的组件化规范,适配性更强。
内容的提问来源于stack exchange,提问作者Lahiru Chandima
相关产品推荐
相关产品推荐

