You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带ProgressBar的CountDownTimer重启应用后如何接续进度

问题修复方案

你原来的实现有两个核心问题:

  • 使用了startCountdown方法内的局部变量i计数,每次调用方法、每次重启应用i都会被重置为1,完全无法对应之前已经走完的倒计时时长,这也是你替换40000变量不生效的核心原因
  • 进度计算逻辑错误,没有基于「已执行时长 = 总时长 - 剩余时长」的比例计算,硬编码总时长导致灵活性差

修复步骤

  1. 先抽离全局常量,统一管理总倒计时时长,避免硬编码,同时你已经有的timeLeftInMilliseconds要声明为全局变量,在onStart生命周期里从SharedPreferences读取持久化的值,读取不到就默认设为总时长
// 全局声明,总倒计时固定为40秒
private val TOTAL_COUNTDOWN_MILLIS = 40000L
// 全局存储剩余倒计时毫秒数
private var timeLeftInMilliseconds = TOTAL_COUNTDOWN_MILLIS
// 全局持有CountDownTimer实例,方便退出时取消避免内存泄漏
private var countDownTimer: CountDownTimer? = null
  1. 删掉局部计数变量i,直接用剩余时长和总时长的比例计算进度,启动倒计时前先计算初始进度赋值给ProgressBar,避免启动后第一秒进度为0的问题,修改后的startCountdown实现如下:
private fun startCountdown() {
    // 先设置初始进度,应用启动后立刻显示正确进度
    val initProgress = ((TOTAL_COUNTDOWN_MILLIS - timeLeftInMilliseconds) * 100 / TOTAL_COUNTDOWN_MILLIS).toInt()
    myProgressBar.progress = initProgress

    // 先取消之前可能存在的倒计时实例,避免重复执行
    countDownTimer?.cancel()
    countDownTimer = object : CountDownTimer(timeLeftInMilliseconds, 1000) {
        override fun onTick(millisUntilFinished: Long) {
            timeLeftInMilliseconds = millisUntilFinished
            // 直接用时间差计算进度,不需要额外计数变量
            val progress = ((TOTAL_COUNTDOWN_MILLIS - millisUntilFinished) * 100 / TOTAL_COUNTDOWN_MILLIS).toInt()
            myProgressBar.progress = progress
        }

        override fun onFinish() {
            myProgressBar.progress = 100
            timeLeftInMilliseconds = TOTAL_COUNTDOWN_MILLIS
        }
    }.start()
}
  1. 补充onStop里的执行逻辑,退出页面时先取消倒计时再存剩余时间,避免存到错误的中间值:
override fun onStop() {
    super.onStop()
    countDownTimer?.cancel()
    // 此处将timeLeftInMilliseconds写入SharedPreferences持久化即可
}

内容的提问来源于stack exchange,提问作者The Fluffy T Rex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 13:06:08