Android弹出AlertDialog报runtime_flags:0x8000错误如何解决
报错原因
- 核心触发原因是构造
AlertDialog.Builder时传入的mContext不符合要求:绝大多数场景下是传入了Application级别的上下文,而非当前正在前台、未销毁的Activity实例。0x8000对应的是系统窗口标记FLAG_ACTIVITY_NEW_TASK,Application上下文启动窗口时默认会带上该标记,而AlertDialog属于依附于Activity的非独立子窗口,系统校验Dialog窗口的runtime_flags时,不识别这个不属于子窗口范畴的标记位,就会抛出该错误。该问题和运行设备是模拟器还是实体机无关,在Android 10及以上系统上只要Context传错就会稳定复现。 - 代码里的额外隐患:你inflate自定义Dialog布局时,用的是点击事件传入View
v的Context获取LayoutInflater,如果这个View不属于当前Activity(比如是RecyclerView的itemView、悬浮窗挂载的View),会进一步导致上下文来源不匹配,提升异常出现概率。
修复方案
- 构造
AlertDialog.Builder时,直接传入当前未销毁的Activity实例作为上下文,不要使用全局存储的Application Context、或者来源不明的Context对象。如果这段代码直接写在Activity内部,直接传当前Activity类名.this即可,不要用提前定义的mContext变量(除非你能100%确认该变量赋值的是当前存活的Activity实例)。 - inflate Dialog自定义布局时,统一使用当前Activity获取LayoutInflater实例,不要依赖点击事件里View返回的Context,避免上下文来源不一致。
- 调用
show()方法前增加Activity存活状态校验,避免Activity已经销毁时强制弹出Dialog触发额外的窗口泄漏异常。
修复后的可运行代码示例:
// 替换为你自己的Activity类名,传入Activity级别的Context AlertDialog.Builder builder = new AlertDialog.Builder(AbcActivity.this); // 统一用Activity的inflate服务加载布局,不要依赖点击View的Context View dialogView = LayoutInflater.from(AbcActivity.this).inflate(R.layout.activity_abc, null, false); builder.setView(dialogView); btnSubmit = (Button) dialogView.findViewById(R.id.submitButton); btnCancel = (Button) dialogView.findViewById(R.id.cancelBtn); btnSubmit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { doSomething(); } }); btnCancel.setOnClickListener((View view) -> alertDialog.dismiss()); alertDialog = builder.create(); // 校验Activity状态后再弹出,避免窗口泄漏 if (!isFinishing() && !isDestroyed()) { alertDialog.show(); }
补充说明:部分机型会把该flag异常打成error级日志但不会直接崩溃,但这本质是Context使用错误的明确提示,修正Context传入值后,该日志会完全消失,Dialog也可以正常弹出。
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

