Android自动更新功能仅调试模式触发BadTokenException崩溃问题求助
问题排查结论
崩溃的根因是Toast显示时绑定的Activity已经被销毁,窗口令牌失效,报错栈对应的android.view.WindowManager$BadTokenException: Unable to add window异常明确指向Toast显示阶段的上下文错误。
调试和直接运行表现不一致的原因:直接运行时代码执行速度快,所有Toast都在当前Activity跳转到系统安装页(触发生命周期销毁)之前完成渲染;调试模式下断点会暂停代码执行,等到后续Toast要显示时,原Activity已经被系统回收,所以触发崩溃。
具体修复方案
1. 修正Toast的上下文引用
你当前代码中catch分支、无更新分支的Toast使用的是Activity实例作为上下文,当Activity销毁后就会触发token失效问题,统一替换为ApplicationContext即可:
// 原有错误写法 Toast.makeText(this, "Ошибка обновления программы", Toast.LENGTH_SHORT).show(); // 修正为 Toast.makeText(getApplicationContext(), "Ошибка обновления программы", Toast.LENGTH_SHORT).show();
2. 补全空判断避免空指针
listFiles方法在目录无读取权限或者路径非法时会返回null,直接访问files.length会触发空指针崩溃,增加非空校验:
File[] files = fDir.listFiles(FilenameFilterAPK); // 增加files非空判断 if (files != null && files.length > 0) { // 原有更新逻辑 } else { Toast.makeText(getApplicationContext(), "Обновления программы нет", Toast.LENGTH_SHORT).show(); }
3. 修正FileProvider调用与配置
你当前FileProvider.getUriForFile的第二个参数必须和AndroidManifest.xml中注册的FileProvider的android:authorities属性完全一致,不能直接填包名,常规配置如下:
第一步:Manifest中注册FileProvider
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
第二步:修正FileProvider调用代码
fileUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", file);
4. 补全安装权限与Intent配置
Android 8.0及以上版本需要申请安装未知来源应用权限,同时补全Intent必要标识避免适配问题:
第一步:Manifest中添加权限
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
第二步:修改安装Intent配置
Intent intent1 = new Intent(Intent.ACTION_INSTALL_PACKAGE); intent1.setData(fileUri); // 增加新任务栈标识 intent1.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK); intent1.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true); startActivity(intent1);
内容的提问来源于stack exchange,提问作者Darsi
相关产品推荐
相关产品推荐

