AppUpdateManager.startUpdateFlowForResult触发IntentSender$SendIntentException问题:应用内更新多次触发仅首次有效
问题分析与解决方案
我之前也碰到过这个In-app更新的坑,咱们先拆解一下异常的原因,再给你具体的修复方案:
为什么会抛出IntentSender$SendIntentException?
你的代码里有两个关键问题:
- 复用了一次性的
AppUpdateInfoTask:你在init()里提前获取了appUpdateInfoTask,这个Task是一次性的——一旦它完成(成功/失败),后续再调用addOnSuccessListener只会立刻返回之前缓存的结果,而不会重新向Google Play请求最新的更新状态。当用户首次取消更新后,这个旧的AppUpdateInfo的状态已经失效(比如变成CANCELLED),再用它启动更新流程自然会报错。 - 没有检查更新状态的有效性:即使你重新获取了
AppUpdateInfo,如果不先验证它是否处于可更新的状态(比如是否真的有可用更新、更新类型是否允许),直接启动流程也可能触发异常。
修复方案
1. 每次检查更新都重新获取最新的AppUpdateInfo
不要提前缓存appUpdateInfoTask,而是在每次调用checkAppUpdate()时重新发起请求,确保拿到的是Google Play最新的更新状态:
private void init() { // 只初始化AppUpdateManager,不要提前获取AppUpdateInfoTask appUpdateManager = AppUpdateManagerFactory.create(mContext); } public void checkAppUpdate() { // 每次检查都重新请求最新的更新信息 appUpdateManager.getAppUpdateInfo() .addOnSuccessListener(appUpdateInfo -> { // 先验证更新状态是否符合要求 if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE && appUpdateInfo.isUpdateTypeAllowed(appUpdateType)) { startAppUpdate(appUpdateInfo); } else { Log.d(TAG, "No valid update available or update type not allowed"); } }) .addOnFailureListener(e -> { Log.e(TAG, "Failed to fetch app update info", e); }); }
2. 在启动更新时捕获异常并重试
即使做了状态检查,偶尔还是可能因为状态过期或Activity生命周期问题触发异常,所以要捕获IntentSender.SendIntentException,并在异常发生时重新检查更新:
private void startAppUpdate(AppUpdateInfo appUpdateInfo) { Log.d(TAG, "startAppUpdate: starting app update"); // 确保Activity引用有效 if (mActivityReference.get() == null || mActivityReference.get().isFinishing()) { Log.w(TAG, "Activity is not available to start update flow"); return; } try { appUpdateManager.startUpdateFlowForResult( appUpdateInfo, appUpdateType, mActivityReference.get(), mRequestCode); } catch (IntentSender.SendIntentException e) { Log.e(TAG, "Failed to start update flow, retrying...", e); // 异常后重新获取最新状态并尝试 checkAppUpdate(); } }
3. 注意Activity引用的有效性
如果你的mActivityReference是WeakReference,一定要在启动更新前检查Activity是否还活跃,避免因为Activity已销毁而触发异常。
额外提示
- 如果你用的是灵活更新(Flexible Update),还要记得在用户取消更新后,后续检查时允许重新触发更新——Google Play默认会在一段时间后允许再次请求,但通过重新获取
AppUpdateInfo可以确保立即拿到最新的状态。 - 测试时可以用Google Play内部测试或封闭测试渠道,确保更新包已上传并处于可获取状态。
内容的提问来源于stack exchange,提问作者Asif A. Sohan
相关产品推荐
相关产品推荐

