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

应用运行中突发崩溃,报WindowManager$BadTokenException错误求助

解决Android中WindowManager$BadTokenException(Toast崩溃)问题

兄弟,你遇到的这个崩溃我太熟了——看调用栈明显是Toast搞的鬼!android.view.WindowManager$BadTokenException本质就是:你要显示的Toast找不到有效的Activity窗口依附了,那个BinderProxy@aba286f就是已经失效的Activity窗口令牌。

问题根源

从调用栈里的Toast$TN.handleShow能看出来,你肯定是在Activity已经销毁之后(比如调用了finish()、屏幕旋转重建前、App后台太久被系统回收),还在尝试显示Toast。这时候Activity的窗口已经不存在了,系统当然不让你添加新的Toast窗口。

具体解决方案

我给你几个实用的解决办法,按场景选就行:

1. 显示Toast前先检查Activity状态

最直接的方式:在调用Toast.show()之前,先确认Activity还活着:

// 在Activity里直接用
if (!isFinishing() && !isDestroyed()) {
    Toast.makeText(this, "你的提示内容", Toast.LENGTH_SHORT).show();
}

如果是在Fragment里,记得先判空Activity:

Activity activity = getActivity();
if (activity != null && !activity.isFinishing() && !activity.isDestroyed()) {
    Toast.makeText(activity, "Fragment里的提示", Toast.LENGTH_SHORT).show();
}

2. 用Application Context显示Toast(简单但有局限)

如果你的Toast不需要自定义位置,也可以用全局的Application Context来创建:

Toast.makeText(getApplicationContext(), "全局提示", Toast.LENGTH_SHORT).show();

⚠️ 注意:这种Toast默认显示在屏幕中间,而且没法用setGravity()改位置,因为它不依附任何Activity窗口。如果需要调整位置,还是用方案1。

3. 异步场景用弱引用持有Activity

如果是在网络请求、子线程回调这种异步操作里显示Toast,很容易遇到Activity已经销毁的情况。这时候用弱引用持有Activity,既能避免内存泄漏,又能检查状态:

// 在Activity里初始化弱引用
private WeakReference<Activity> mActivityRef;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mActivityRef = new WeakReference<>(this);
}

// 异步回调里使用
private void onAsyncTaskFinish() {
    Activity activity = mActivityRef.get();
    if (activity != null && !activity.isFinishing() && !activity.isDestroyed()) {
        Toast.makeText(activity, "异步任务完成啦", Toast.LENGTH_SHORT).show();
    }
}

4. 封装一个安全的Toast工具类(一劳永逸)

如果App里经常需要显示Toast,不如封装个工具类,内部自动处理Activity状态:

public class SafeToastUtil {
    public static void show(Activity activity, String message) {
        show(activity, message, Toast.LENGTH_SHORT);
    }

    public static void show(Activity activity, String message, int duration) {
        if (activity != null && !activity.isFinishing() && !activity.isDestroyed()) {
            Toast.makeText(activity, message, duration).show();
        }
    }
}

// 使用的时候直接调用就行
SafeToastUtil.show(this, "再也不会崩溃的提示");

总结

核心思路就是确保显示Toast时,对应的Activity处于活跃状态——别在Activity生命周期结束后(比如onDestroy()之后、finish()之后)调用Toast.show(),就能避免这个崩溃啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:14:44