Android应用内更新陷入无限循环问题排查
应用内更新(In-app Update)无限安装循环问题排查
我正在实现应用内更新功能,但测试时遇到无限安装的问题:安装过程始终无法完成,按下返回键回到应用主界面后,更新界面会立即再次弹出并进入无限安装状态;即使重启应用(包括强制停止)、清除数据和缓存,问题依然存在,更新弹窗会反复出现。

核心实现代码
class InAppUpdateTestHelper( private val activity: Activity, lifecycleOwner: LifecycleOwner, private val startUpdateFlowForResult: ActivityResultLauncher<IntentSenderRequest>, ) { private val appUpdateManager by lazy { AppUpdateManagerFactory.create(activity) } init { try { val defaultLifecycleObserver = object : DefaultLifecycleObserver { override fun onResume(owner: LifecycleOwner) { checkIfAppUpdateInProgress() } } lifecycleOwner.lifecycle.addObserver(defaultLifecycleObserver) } catch (e: Throwable) { e.printStackTrace() } forceUpdate() } private fun forceUpdate() { try { appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo -> try { val updateAvailable = appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE val isUpdateImmediateAllowed = appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE) if (updateAvailable && isUpdateImmediateAllowed) { appUpdateManager.startUpdateFlowForResult( appUpdateInfo, // an activity result launcher registered via registerForActivityResult startUpdateFlowForResult, AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE) .build() ) } } catch (e: Throwable) { e.printStackTrace() } }.addOnFailureListener { Timber.e("appUpdateInfo addOnFailureListener ${it.message}") } } catch (e: Throwable) { e.printStackTrace() } } private fun checkIfAppUpdateInProgress() { val startUpdateFlowForResult = startUpdateFlowForResult ?: return try { appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo -> if (appUpdateInfo.updateAvailability() == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) { try { appUpdateManager.startUpdateFlowForResult( appUpdateInfo, // an activity result launcher registered via registerForActivityResult startUpdateFlowForResult, AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE) .build() ) } catch (e: Throwable) { e.printStackTrace() } } } } catch (e: Throwable) { e.printStackTrace() } } }
Activity初始化代码
private val startUpdateFlowForResult = registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result -> // handle callback if (DEBUG) { val resultCode = result.resultCode Timber.d("startUpdateFlowForResult $resultCode") } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) inAppUpdateTestHelper = InAppUpdateTestHelper( activity = this, lifecycleOwner = this, startUpdateFlowForResult = startUpdateFlowForResult, ) }
更新信息
- 问题出现在三星S22(Android 14)设备上,三星S10(Android 12)测试正常
- 清除三星S22上Google Play的数据和缓存后,问题仍未解决
- 计划在Android 14的Pixel模拟器上进一步测试
问题原因及修复方案
1. 核心问题
当用户取消更新返回应用时,Play Core未正确重置DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS状态,加上初始化时直接调用forceUpdate()、onResume中重复检查触发更新,形成了循环。
2. 具体修复步骤
(1)避免初始化时立即触发更新
移除init中的forceUpdate(),改为外部在合适时机调用,并添加触发条件:
// 修改InAppUpdateTestHelper的init和新增方法 init { try { val defaultLifecycleObserver = object : DefaultLifecycleObserver { override fun onResume(owner: LifecycleOwner) { checkIfAppUpdateInProgress() } } lifecycleOwner.lifecycle.addObserver(defaultLifecycleObserver) } catch (e: Throwable) { e.printStackTrace() } } fun checkAndStartUpdate() { forceUpdate() }
Activity中仅首次创建时触发:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) inAppUpdateTestHelper = InAppUpdateTestHelper( activity = this, lifecycleOwner = this, startUpdateFlowForResult = startUpdateFlowForResult, ) // 仅Activity首次创建时检查更新 if (savedInstanceState == null) { inAppUpdateTestHelper.checkAndStartUpdate() } }
(2)处理回调结果,主动重置状态
在更新回调中处理取消/失败场景,调用completeUpdate()终止更新流程:
private val startUpdateFlowForResult = registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result -> when(result.resultCode) { Activity.RESULT_CANCELED, Activity.RESULT_FIRST_USER -> { // 用户取消或更新失败,重置状态 appUpdateManager.appUpdateInfo.addOnSuccessListener { info -> if (info.updateAvailability() == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) { appUpdateManager.completeUpdate() } } } } if (DEBUG) { Timber.d("startUpdateFlowForResult ${result.resultCode}") } }
(3)适配Android 14
确保使用最新版本的Play Core库(至少com.google.android.play:core:1.10.3),并更新设备上的Google Play服务。
(4)添加频率限制
用SharedPreferences记录检查时间,避免短时间内重复触发:
private fun shouldCheckUpdate(): Boolean { val sp = activity.getSharedPreferences("update_prefs", Context.MODE_PRIVATE) val lastCheck = sp.getLong("last_update_check", 0) val interval = 3600 * 1000 // 1小时间隔 if (System.currentTimeMillis() - lastCheck > interval) { sp.edit().putLong("last_update_check", System.currentTimeMillis()).apply() return true } return false } // 修改checkAndStartUpdate fun checkAndStartUpdate() { if (shouldCheckUpdate()) { forceUpdate() } }
内容的提问来源于stack exchange,提问作者user924
相关产品推荐
相关产品推荐

