Android视图管理器$BadTokenException: 无法添加窗口--令牌android.os.BinderProxy@b0baaa1无效; 您的活动是否正在运行?

4

最近我在使用Android 7.1.1时常常遇到一个错误,提示toast出现了崩溃情况。这很奇怪,有没有别人也遇到过同样的问题呢?

android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@b0baaa1 is not valid; is your activity running?
at android.view.ViewRootImpl.setView(ViewRootImpl.java:812)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:351)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
at android.widget.Toast$TN.handleShow(Toast.java:489)
at android.widget.Toast$TN$2.handleMessage(Toast.java:360)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6475)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1134)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995)

展示代码出现的位置。 - himel
在我的 build.gradle 文件中,将目标 API 级别更新为 26 后,我遇到了同样的问题。我回滚到 25 并且现在它正常工作了。 - Andrew Starostin
1
我也遇到了这个问题。唯一能够重现它的方法是在 setContentView 之前放置 Toast。但即使我将它们移除后,仍然收到这个错误报告。而且我找不到一种方法来检查它是否已经在运行中。 - Kimi Chiu
1
我遇到了同样的问题,而且我的目标API级别也是26。 - drakeet
1
目前,Google不允许上传目标API设置为25的APK。我仍然在现场看到客户运行Android 7.1时遇到此问题。(我的目标API是27)。 - Venu G.
我也遇到了同样的BadTokenException问题。我使用的是Nexus 6手机。我在一个片段中有一个网格布局,当我点击其中一个项目时(其他片段需要更新),有时toast可以正常工作,但有时会崩溃。我已经将我的targetSDK更改为26。 - Sachz
5个回答

5
当使用已不在前台的Activity的上下文显示Toast时,会发生错误。解决方案是仅在检查活动仍处于活动状态且未处于完成状态之前显示Toast。这可能并不总是最佳解决方案,因为有些情况下Toast可能会以异步方式显示,例如在异步任务中,并在Activity不再处于活动状态时出现,这将导致崩溃。
下一个库详细解释了为什么会崩溃,在Android中引入该问题的原因,并通过捕获错误来解决问题:

https://github.com/drakeet/ToastCompat


从你所说的来看,这个问题存在于Android 7.1(API 25)中,但是修复已经纳入了Android 8.0(API 26)。你知道它是否被纳入任何7.1.X更新吗? - Venu G.
1
我不知道API 25的任何更新是否已经引入了修复,但如果Google实施了它,那么每个供应商都有责任部署它,但这并不总是发生。在这种情况下,最安全的方法是使用ToastCompat库。 - PerracoLabs

3

你使用Leak Canary吗?有一个公开问题与Toast消息相关联。

看起来Leak Canary试图使用不存在的上下文来通知用户有关泄漏的信息。


我在生产环境中收到了这个错误报告,其中leakcanary是不活动的,因此尽管这可能是一种可能性,但它也可能发生在没有它的情况下。 - behelit

0

我曾经在一个Android应用程序中遇到过类似的问题,在该应用程序中,我从Alert Dialogbox中选择单个选择后调用了一个新的活动。这个错误发生是因为代码的执行是异步的,新的活动被启动并且定义了Alert Dialog框的活动已经完成。这意味着上下文已经改变。

如果您仔细查看错误消息,它指向"alertDialog.show()"这一行。

所以你应该检查一下你的活动(其中定义了警报对话框)是否在显示警报之前结束了。请看下面的代码:

if (!isFinishing) {
  alertDialog.show()
}

0

尝试使用以下方式包装Toast

if(!getActivity().isFinishing())
{
    //show toast
}

编辑:

如果你正在使用活动上下文,请尝试将Toast的上下文更改为getApplicationContext()


0

我也遇到了android.view.WindowManager$BadTokenException错误。我的活动在服务上运行,并且第一个片段中有一个网格视图。当我点击一个项目时,相关信息将传递到另外2个片段,并且当选择一个项目时还会出现Toast。在这里,我收到了(有时可以正常工作而没有异常 - 这很奇怪)BadTokenException,并且应用程序崩溃了。我正在使用Nexus 6手机。

  1. 我将 targetSdkVersion 从29改为26。(PS:我不确定这一步是否正确。由于我的意图是仅在Nexus 6上使用该应用程序,因此我将其从29更改为26) enter image description here

  2. 然后我将 Toast 移动到所有函数的底部。(最初,我的Toast位于所有函数的顶部。)现在Toast会在片段更新后出现。

    @Override public void onItemDeviceSelected(String mac, String name) {

    if(!mService.getItem(mac).isLive()){
    
        //Functions() to pass the selected items relevant information to the 2 other fragments
    …………
    ……….
    
        Toast.makeText(this, "Selected: " + name + "\n" + Add, Toast.LENGTH_SHORT).show();
    
        Log.d();
    } else{
        Toast.makeText(this, "Selected: " + name + " " + "is LIVE. Unable to select", Toast.LENGTH_SHORT).show();
    }
    

    }

目前我没有收到异常(谢天谢地)。我尝试选择网格项多次。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接