为什么Android应用内更新(In-app updates)未按预期正常生效?
你修改后的代码已经解决了最初固定2500毫秒延时跳转导致更新弹窗被强制关闭的问题,但还有几处逻辑缺失需要修复:
现存问题
- 调用
startUpdateFlowForResult弹出更新弹窗后,没有对更新流程的返回结果做对应处理,更新结束后(不管成功/失败/用户取消)没有对应的跳转/拦截逻辑 - 没有监听即时更新的安装状态,无法确认更新是否完成
- 缺少页面重回前台时的更新状态校验,可能出现后台切回后更新弹窗消失的问题
- 没有处理获取更新信息失败的场景,容易出现卡屏
修复方案
1. 添加全局变量和更新状态监听
private lateinit var appUpdateManager: AppUpdateManager private val updateRequestCode = 1612 // 更新状态监听回调 private val installStateUpdatedListener = InstallStateUpdatedListener { state -> when (state.installStatus()) { InstallStatus.DOWNLOADED -> { // 下载完成后自动触发安装 appUpdateManager.completeUpdate() } InstallStatus.FAILED, InstallStatus.CANCELED -> { // 即时更新场景下,更新失败或用户取消直接退出应用,不允许进入 Toast.makeText(this@SplashActivity, "请更新到最新版本后使用", Toast.LENGTH_SHORT).show() finish() } else -> {} } }
2. 优化callInAppUpdate方法
将跳转逻辑抽成公共方法,同时添加获取更新信息失败的容错处理:
private fun callInAppUpdate() { appUpdateManager = AppUpdateManagerFactory.create(this) // 注册更新状态监听 appUpdateManager.registerListener(installStateUpdatedListener) val appUpdateInfoTask = appUpdateManager.appUpdateInfo appUpdateInfoTask.addOnSuccessListener { appUpdateInfo -> if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE) ) { appUpdateManager.startUpdateFlowForResult( appUpdateInfo, AppUpdateType.IMMEDIATE, this, updateRequestCode ) }else{ // 无可用更新,延时跳转到对应页面 Handler(Looper.getMainLooper()).postDelayed({ navigateToNextPage() }, 2500) } } // 新增获取更新信息失败的容错,避免卡屏 appUpdateInfoTask.addOnFailureListener { Handler(Looper.getMainLooper()).postDelayed({ navigateToNextPage() }, 2500) } } // 抽离公共跳转逻辑,避免重复代码 private fun navigateToNextPage() { val currentUserID = FirestoreClass().getCurrentUserID() if (currentUserID.isNotEmpty()) { startActivity(Intent(this@SplashActivity, DashboardActivity::class.java)) } else { startActivity(Intent(this@SplashActivity, LoginWithPhoneNumberActivity::class.java)) } finish() }
3. 完善onActivityResult逻辑
处理用户在更新弹窗上的操作结果:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == updateRequestCode) { when(resultCode) { RESULT_OK -> { Toast.makeText(this, "正在下载更新", Toast.LENGTH_SHORT).show() } RESULT_CANCELED -> { Toast.makeText(this@SplashActivity, "请更新到最新版本后使用", Toast.LENGTH_SHORT).show() finish() } ActivityResult.RESULT_IN_APP_UPDATE_FAILED -> { Toast.makeText(this@SplashActivity, "更新失败,请稍后重试", Toast.LENGTH_SHORT).show() finish() } } } }
4. 新增onResume状态校验
解决切后台后返回应用更新弹窗消失的问题:
override fun onResume() { super.onResume() if (this::appUpdateManager.isInitialized) { appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo -> // 检查是否有未完成的即时更新,重新拉起更新流程 if (appUpdateInfo.updateAvailability() == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) { appUpdateManager.startUpdateFlowForResult( appUpdateInfo, AppUpdateType.IMMEDIATE, this, updateRequestCode ) } } } }
5. 页面销毁时移除监听,避免内存泄漏
override fun onDestroy() { super.onDestroy() if (this::appUpdateManager.isInitialized) { appUpdateManager.unregisterListener(installStateUpdatedListener) } }
注意事项
测试应用内更新时,需要确保测试机上安装的应用版本号低于Google Play后台发布的版本,且签名与Play后台上传的安装包签名一致,才能正常触发更新弹窗。
内容的提问来源于stack exchange,提问作者Codist
相关产品推荐
相关产品推荐

