You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

android.view.WindowManager$BadTokenException修复及应用崩溃率问题咨询

问题1:android.view.WindowManager$BadTokenException 崩溃定位与修复

异常根因

从你提供的崩溃堆栈可以直接定位触发点:

android.view.WindowManager$BadTokenException: 
  at android.view.ViewRootImpl.setView (ViewRootImpl.java:1126)
  at android.view.WindowManagerGlobal.addView (WindowManagerGlobal.java:439)
  at android.view.WindowManagerImpl.addView (WindowManagerImpl.java:95)
  at android.app.Dialog.show (Dialog.java:473)
  at androidx.appcompat.app.AlertDialog$Builder.show (AlertDialog.java:1009)
  at com.easyadsmm.androidapp.SplashScreen$1.onFailure (SplashScreen.java:508)
  at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1.lambda$onFailure$1 (DefaultCallAdapterFactory.java:96)
  ...

该异常的核心原因是你尝试弹窗的Activity上下文已经失效:SplashScreen启动页发起的Retrofit异步请求返回失败时,用户已经关闭了启动页(比如按返回键回到桌面、切到其他应用),此时Activity已经走了销毁流程,再用这个失效的Activity作为Context弹AlertDialog就会触发该异常。

修复方案

  • 弹窗前增加Activity状态校验:调用isFinishing()和isDestroyed()方法判断页面状态,只有两个方法都返回false时再执行弹窗逻辑,示例代码如下:
// SplashScreen.java第508行附近的onFailure回调中修改逻辑
@Override
public void onFailure(Call<T> call, Throwable t) {
    // 先校验页面状态
    if (SplashScreen.this.isFinishing() || SplashScreen.this.isDestroyed()) {
        return;
    }
    // 原有弹窗逻辑
    new AlertDialog.Builder(SplashScreen.this)
            // 你的弹窗配置
            .show();
}
  • 页面销毁时取消未完成的网络请求:在SplashScreen的onDestroy()生命周期方法中,对本次发起的Retrofit请求调用cancel()方法,避免页面销毁后回调继续执行。
  • 兜底方案(非必要不推荐):如果该弹窗不需要绑定启动页生命周期,可以使用ApplicationContext创建弹窗,但需要额外申请悬浮窗权限,优先使用前两个方案即可覆盖绝大多数异常场景。
问题2:崩溃率水平评估

10.7%的崩溃率属于极高风险水平,行业通用的标准是:头部应用崩溃率要求低于0.1%,普通成熟应用崩溃率也会控制在1%以下。
你当前的应用上线仅2个月,用户基数较小,少量崩溃就会大幅拉高整体崩溃率,只要持续跟进修复所有上报的异常问题,后续用户量上升后崩溃率会快速回落至正常区间。

内容的提问来源于stack exchange,提问作者DB_cont

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 04:45:04