
点击按钮时先增加第一个分数,5 秒后再自动增加第二个分数,避免 UI 阻塞和逻辑耦合,推荐使用协程的 delay() 实现异步延时操作。
点击按钮时先增加第一个分数,5 秒后再自动增加第二个分数,避免 ui 阻塞和逻辑耦合,推荐使用协程的 `delay()` 实现异步延时操作。
在 Android 开发中,若需实现“单次点击触发两阶段状态变更”(如先更新 firstTeamScore,5 秒后更新 secondTeamScore),直接在主线程中调用 Thread.sleep() 会阻塞 UI,而 CountDownTimer 在此场景下易与按钮逻辑耦合、难以复用且状态管理复杂。更简洁、现代且安全的方案是使用 Kotlin 协程。
以下是推荐实现方式:
binding.trueButton.setOnClickListener {
// 立即更新第一个分数
firstTeamScore++
binding.scoreText.text = firstTeamScore.toString()
// 启动协程,在主线程安全地延时执行第二步
lifecycleScope.launch {
delay(5000) // 非阻塞式延时(单位:毫秒)
secondTeamScore++
binding.scoreText.text = secondTeamScore.toString()
}
}
✅ 关键优势说明:
- 使用
lifecycleScope(而非CoroutineScope(Dispatchers.Main).async)可自动绑定 Fragment/Activity 生命周期,防止内存泄漏或在组件销毁后更新 UI; -
delay()是协程挂起函数,不阻塞线程,比CountDownTimer更轻量、更易读; - 所有 UI 操作均在主线程安全执行,无需手动切回
Dispatchers.Main。
⚠️ 注意事项:
确保已添加协程依赖:
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.8.0"(或最新稳定版);-
若需支持多次点击并取消前序延时任务(例如防重复触发),可结合
Job管理:private var pendingSecondUpdate: Job? = null binding.trueButton.setOnClickListener { firstTeamScore++ binding.scoreText.text = firstTeamScore.toString() pendingSecondUpdate?.cancel() // 取消上一次未完成的延时 pendingSecondUpdate = lifecycleScope.launch { delay(5000) secondTeamScore++ binding.scoreText.text = secondTeamScore.toString() } }
该方案结构清晰、可维护性强,符合现代 Android 开发最佳实践。










