LicenseClientV3(LicenseClientV3.java:248)崩溃 - BadTokenException问题求助
问题分析与解决方案:第三方License库触发WindowManager$BadTokenException
问题背景
捕获到如下崩溃,无法复现,且异常来自第三方类com.pairip.licensecheck3.LicenseClientV3,无法直接修改该类代码:
Fatal Exception: android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@500b830 is not valid; is your activity running? at android.view.ViewRootImpl.setView(ViewRootImpl.java:1153) at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:399) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:133) at android.app.Dialog.show(Dialog.java:345) at android.app.AlertDialog$Builder.show(AlertDialog.java:1131) at com.pairip.licensecheck3.LicenseClientV3.lambda$showErrorDialog$2$com-pairip-licensecheck3-LicenseClientV3(LicenseClientV3.java:248) at com.pairip.licensecheck3.LicenseClientV3$$ExternalSyntheticLambda4.run(:2) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7839) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
原因分析
从堆栈可见,第三方库在showErrorDialog方法中通过Handler.post延迟弹出AlertDialog,但此时传入Dialog的Context对应的Activity已被销毁(token失效),导致无法添加Window触发异常。本质是异步操作完成后,第三方库未判断Activity的生命周期状态。
可行解决方案
控制第三方库调用时机:梳理调用LicenseClientV3的代码,确保仅在Activity的
onResume至onPause区间触发相关操作。若第三方库自动执行逻辑,可通过注册Activity生命周期回调,在Activity销毁时尝试取消其异步任务(需依赖库提供的公开API)。全局异常兜底捕获:在Application中设置全局异常处理器,捕获该类型异常避免崩溃:
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> { if (throwable instanceof WindowManager.BadTokenException) { Log.e("ThirdPartyCrash", "拦截第三方库BadToken异常", throwable); } else { // 其他异常交给原有处理逻辑 defaultHandler.uncaughtException(thread, throwable); } });注:此方式仅为临时兜底,未解决根本问题。
字节码修改拦截Dialog弹出:使用ByteBuddy、ASM等工具,在编译或运行期修改第三方库的
showErrorDialog方法,添加Activity状态判断:// 示例逻辑(需适配第三方库实际代码) if (activity != null && !activity.isFinishing() && !activity.isDestroyed()) { dialog.show(); }注:需注意合规性,避免违反第三方库许可协议。
内容的提问来源于stack exchange,提问作者Gelson Schikorski
相关产品推荐
相关产品推荐

