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

Android应用离线倒计时恢复生命值功能实现求助

解决Android生命值系统后台计时与离线恢复问题

核心思路

先解决问题B(离线时间计算),这是基础——不要依赖实时倒计时,改用「时间戳差值计算」,再用WorkManager处理后台定时更新,解决问题A。


问题B:应用关闭后恢复生命值的解决方案

不管应用是否运行,核心是记录「最后一次生命值变更的时间戳」,每次需要更新生命值时(应用启动、后台任务触发),计算当前时间与上次时间的差值,算出应恢复的生命值:

  1. 存储关键数据:用SharedPreferences存两个值
    • 当前生命值current_lives
    • 最后一次生命值更新的时间戳last_update_timestamp(毫秒级)
  2. 计算逻辑:
    • 获取当前时间戳,算出与上次更新的时间差
    • 按每小时1条计算可恢复数量,不超过上限10条
    • 更新生命值和时间戳

代码实现(存储与计算工具类)

object LiveDataManager {
    private const val PREF_NAME = "LiveSystemPrefs"
    private const val KEY_CURRENT_LIVES = "current_lives"
    private const val KEY_LAST_UPDATE = "last_update_timestamp"
    private const val MAX_LIVES = 10
    private const val RECOVERY_INTERVAL = 60 * 60 * 1000L // 1小时

    // 更新生命值(核心计算逻辑)
    fun updateLives(context: Context): Int {
        val prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
        val currentLives = prefs.getInt(KEY_CURRENT_LIVES, 10) // 默认满生命值
        val lastUpdate = prefs.getLong(KEY_LAST_UPDATE, System.currentTimeMillis())
        val now = System.currentTimeMillis()
        val timeDiff = now - lastUpdate

        // 计算可恢复的生命值
        val recoverableLives = (timeDiff / RECOVERY_INTERVAL).toInt()
        val newLives = min(currentLives + recoverableLives, MAX_LIVES)

        // 只有生命值变化时才更新存储
        if (newLives != currentLives) {
            prefs.edit()
                .putInt(KEY_CURRENT_LIVES, newLives)
                .putLong(KEY_LAST_UPDATE, now)
                .apply()
        }
        return newLives
    }

    // 扣除生命值(操作失误时调用)
    fun deductLife(context: Context): Int {
        val prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
        val currentLives = prefs.getInt(KEY_CURRENT_LIVES, 10)
        val newLives = max(currentLives - 1, 0)
        prefs.edit()
            .putInt(KEY_CURRENT_LIVES, newLives)
            .putLong(KEY_LAST_UPDATE, System.currentTimeMillis()) // 扣除后更新时间戳
            .apply()
        return newLives
    }

    // 获取当前生命值
    fun getCurrentLives(context: Context): Int {
        return context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
            .getInt(KEY_CURRENT_LIVES, 10)
    }
}

问题A:后台倒计时不运行的解决方案

放弃普通Service,改用WorkManager——这是Google官方推荐的后台任务调度组件,适配Android 8+的后台限制,即使应用在后台或重启,也能可靠触发任务。

步骤1:实现Worker类

class LiveRecoveryWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        // 执行生命值更新逻辑
        LiveDataManager.updateLives(applicationContext)
        // 可选:更新后发送通知提示用户
        return Result.success()
    }
}

步骤2:启动周期性任务

在Application类的onCreate中初始化任务,确保唯一且持续运行:

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        // 每小时执行一次生命值更新任务
        val recoveryWork = PeriodicWorkRequestBuilder<LiveRecoveryWorker>(1, TimeUnit.HOURS)
            .setConstraints(Constraints.Builder()
                .setRequiredNetworkType(NetworkType.NOT_REQUIRED) // 无需网络
                .build())
            .build()

        // 确保任务唯一,避免重复创建
        WorkManager.getInstance(this).enqueueUniquePeriodicWork(
            "LiveRecoveryTask",
            ExistingPeriodicWorkPolicy.KEEP,
            recoveryWork
        )
    }
}

步骤3:Activity中使用

进入页面时先更新生命值,确保UI显示最新状态:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 页面启动时更新生命值
        val currentLives = LiveDataManager.updateLives(this)
        // 更新UI显示currentLives

        // 操作失误扣除生命值示例
        btnDeductLife.setOnClickListener {
            val newLives = LiveDataManager.deductLife(this)
            // 更新UI显示newLives
        }
    }
}

关键说明

  1. 为什么不用Service?
    Android 8+对后台Service有严格限制,后台Service极易被系统回收,导致计时中断。WorkManager会根据系统资源状态调度任务,可靠性远高于普通Service。
  2. 前台实时倒计时怎么处理?
    如果需要在前台显示「距离下次恢复的剩余时间」,可以用CountDownTimer结合LiveData,仅在Activity前台时运行即可——后台的恢复逻辑由WorkManager和时间戳保证,无需前台持续计时。

内容的提问来源于stack exchange,提问作者GIANT

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 21:23:11