美文网首页Android踩坑
BadTokenException问题分析和解决

BadTokenException问题分析和解决

作者: 主音King | 来源:发表于2020-08-06 11:57 被阅读0次

    场景:

    一般在使用Toast和Dialog时候,展示的时候发生异步,展示之前,主线程消息耗时过多导致服务端(SystemService)判断超时或Dialog依赖的Activity被销毁后,发生异常。
    App中遇到另一类BadTokenException问题,在App比较大的工程发生较多。


    腾讯bugly抓到

    Token场景

    Token,全局唯一,整个系统去识别和管理。token并不是客户端进程生成的。那就是服务端产生的。
    启动Activity之前系统端AMS创建ActivityRecord,构造函数内部实例化了一个Token,保证了唯一性,Activity在AMS端唯一标识,基于这个唯一标识进行信息同步和区分。服务端AMS通知客户端实例化Activity的过程。


    image.png
    image.png

    问题分析:从进程崩溃可知,主线程创建Activity(LaunchActivity),此时主线程消息队列所有消息被Block,没有机会执行onDestroy,可能系统向客户端进程发送了scheduleDestroy之后,触发了TimeOut,从而强制触发了Destroy操作并将WindowToken移除。
    受限于系统对App管理,无法从App层获取系统event日志。

    问题分析

    当进程启动一段时间后,并处于后台/前台,如来电/语音电话/Home键。

    解决方案

    Activity第一次执行onResume时,判断是否处于后台以及本次onCreate到onResume时长是否过长,一定概率触发异常;在Activity的onResume调用结束,判断消息队列是否已经存在当前Activity的H.DESTROY_ACTIVITY,如果有该消息,则说明AMS已经将WMS缓存的windowToken移除,客户端主动调用finish接口,可解决。
    通用方案:ActivityManager去监听willActivityBevisible调用,当前Token在服务AMS是否存在;如果不存在则AMS/WMS已经销毁当前Activity的Token对象。主动调用finish,之后addView不要执行。

    相关文章

      网友评论

        本文标题:BadTokenException问题分析和解决

        本文链接:https://www.haomeiwen.com/subject/pzqtrktx.html