大家有没有遇到过只在 Android 7.1 机型上报告的由Toast引起的BadTokenException错误?

发布于 2022-09-06 15:05:42 字数 954 浏览 18 评论 0

由Bugly统计上报,只发生在7.1.1和7.1.2机型上,目前没有复现,所以还没排查出是哪里出了问题。

错误堆栈

# main(1)
android.view.WindowManager$BadTokenException
    Unable to add window -- token android.os.BinderProxy@7f652b2 is not valid; is your activity running?
    android.view.ViewRootImpl.setView(ViewRootImpl.java:826)
    android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:369)
    android.view.WindowManagerImpl.addView(WindowManagerImpl.java:94)
    android.widget.Toast$TN.handleShow(Toast.java:459)
    android.widget.Toast$TN$2.handleMessage(Toast.java:342)
    android.os.Handler.dispatchMessage(Handler.java:102)
    android.os.Looper.loop(Looper.java:185)
    android.app.ActivityThread.main(ActivityThread.java:6493)
    java.lang.reflect.Method.invoke(Native Method)
    com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:916)
    com.android.internal.os.ZygoteInit.main(ZygoteInit.java:806)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

怀中猫帐中妖 2022-09-13 15:05:42

这个问题由于targetSDKVersion升到26之后,在7.1.1机型上概率性出现。稳定复现的步骤是,在Toast.show()之后,UI线程做了耗时的操作阻塞了Handler message的处理,如使用Thread.sleep(5000),然后这个崩溃就出现了。原因是7.1.1系统对TYPE_TOAST的Window类型做了超时限制,绑定了Window Token,最长超时时间是3.5s,如果UI在这段时间内没有执行完,Toast.show()内部的handler message得不到执行,NotificationManageService那端会把这个Toast取消掉,同时把Toast对于的window token置为无效。等App端真正需要显示Toast时,因为window token已经失效,ViewRootImpl就抛出了上面的异常。
Android 8.0上面,google意识到这个bug,在Toast的内部加了try-catch保护。目前只有7.1.1上面的Toast存在这个问题,崩溃在系统源码里。APP层可以通过自定义Toast类,反射替换TN的内部成员变量mHandler,从而添加try-catch做到workaround,所有使用Toast的地方都使用这个自定义的,不要直接使用系统原生的。

冷默言语 2022-09-13 15:05:42

被这个问题困扰了好久,网上各种说法都没能复现在github上找到这个可以参考下:https://github.com/drakeet/To...

不疑不惑不回忆 2022-09-13 15:05:42

其实Toast最好传application的context比较好

孤檠 2022-09-13 15:05:42

你也可以try catch 至少是不会闪退了

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文