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

Google Play崩溃报android.view.WindowManager$BadTokenException如何解决

错误根因

该android.view.WindowManager$BadTokenException报错的核心原因是:onReceivedError是WebView的异步回调,当回调触发时,你传入Dialog构造的facebook.this对应的Activity已经被销毁(比如用户快速返回、切后台被系统回收、deeplink跳转后立即关闭页面等场景),此时尝试依附已经不存在的Activity窗口弹出AlertDialog,系统无法找到对应的窗口令牌就会抛出该异常。

修复步骤
  • 第一步:弹窗之前先校验Activity存活状态
    在调用alertDialog.show()之前,先判断当前Activity是否还处于活跃状态,不活跃就直接终止后续逻辑,同时给弹窗操作加异常捕获兜底:
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
    // 新增:校验Activity状态,已销毁则不执行后续弹窗逻辑
    if (facebook.this.isFinishing() || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && facebook.this.isDestroyed())) {
        return;
    }
    // 原有逻辑
    ViewGroup viewGroup = findViewById(android.R.id.content);
    View dialogView = LayoutInflater.from(facebook.this).inflate(R.layout.errror_dialog, viewGroup, false);
    Button tryagain = dialogView.findViewById(R.id.tryagain);
    AlertDialog.Builder builder = new AlertDialog.Builder(facebook.this);
    builder.setView(dialogView);
    AlertDialog alertDialog = builder.create();
    // 新增:捕获show时的异常,兜底避免崩溃
    try {
        alertDialog.show();
    } catch (WindowManager.BadTokenException e) {
        e.printStackTrace();
        return;
    }
    webview.setVisibility((View.INVISIBLE));
    tryagain.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            // 点击重试时也加状态校验,避免Activity已销毁时报错
            if (facebook.this.isFinishing() || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && facebook.this.isDestroyed())) {
                return;
            }
            webview.reload();
            webview.setVisibility((View.VISIBLE));
            alertDialog.dismiss();
        }
    });
}
  • 第二步:绑定WebView和Activity的生命周期,避免无效回调
    在Activity的onDestroy方法中主动销毁WebView,移除回调监听,避免Activity销毁后WebView还触发onReceivedError:
@Override
protected void onDestroy() {
    if (webview != null) {
        // 先从父容器移除WebView
        ViewParent parent = webview.getParent();
        if (parent instanceof ViewGroup) {
            ((ViewGroup) parent).removeView(webview);
        }
        // 停止加载并清空回调
        webview.stopLoading();
        webview.setWebViewClient(null);
        webview.destroy();
        webview = null;
    }
    super.onDestroy();
}
  • 第三步:可选适配优化
    你当前使用的4参数onReceivedError方法在API 23之后已经被废弃,建议补充实现高版本的新重载方法,保证全版本报错都能被正确处理:
@Override
@TargetApi(Build.VERSION_CODES.M)
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
    // 复用上面的错误处理逻辑即可
    onReceivedError(view, error.getErrorCode(), error.getDescription().toString(), request.getUrl().toString());
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 04:42:00