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

使用Thread.sleep实现TextView每3秒更新商值失败问题求助

问题分析与解决方案

错误根源

  • 时间单位错误:Thread.sleep(3)的参数是毫秒级,你要实现3秒延迟应该传入3000,3毫秒的间隔几乎无法察觉,循环会瞬间执行完毕。
  • UI线程阻塞:division()函数在主线程(UI线程)中执行,Thread.sleep会彻底卡住主线程,导致所有setText操作都要等整个循环结束后才会一次性刷新,最终只显示最后一次计算的结果60(此时分母已减至1,60/1=60)。

推荐修正方案(Kotlin协程)

Kotlin协程是Android官方推荐的异步处理方案,既能避免阻塞UI,又能让代码逻辑清晰易读:

private val TAG = "MainActivity"

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d(TAG, "this is where the app crashed before")
        setContentView(R.layout.activity_main)

        Log.d(TAG, "this should be logged if the bug is fixed.")
        // logging()
        lifecycleScope.launch { // 绑定Activity生命周期,自动避免内存泄漏
            division()
        }
    }

    suspend fun division() {
        val numerator = 60
        var denominator = 4
        repeat(4) {
            delay(3000) // 协程延迟,不阻塞主线程
            findViewById<TextView>(R.id.division_textview).text = "${numerator / denominator}"
            Log.v(TAG, "${numerator / denominator}")
            denominator--
        }
    }
}

关键改动说明

  • lifecycleScope.launch:启动与Activity生命周期绑定的协程,页面销毁时协程自动终止,无需手动管理。
  • suspend fun:标记函数为挂起函数,只能在协程或其他挂起函数内调用。
  • delay(3000):协程专属延迟函数,仅暂停当前协程执行,主线程可正常处理UI渲染,确保每次计算后TextView实时更新。
  • 修正延迟时长:将3改为3000,实现3秒间隔。

备选方案(Handler基础实现)

若想先理解传统线程通信机制,可使用Handler实现:

private val TAG = "MainActivity"
private val handler = Handler(Looper.getMainLooper())

class MainActivity : AppCompatActivity() {
    private var denominator = 4
    private val numerator = 60

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d(TAG, "this is where the app crashed before")
        setContentView(R.layout.activity_main)

        Log.d(TAG, "this should be logged if the bug is fixed.")
        // logging()
        startDivisionUpdates()
    }

    private fun startDivisionUpdates() {
        val updateRunnable = object : Runnable {
            override fun run() {
                findViewById<TextView>(R.id.division_textview).text = "${numerator / denominator}"
                Log.v(TAG, "${numerator / denominator}")
                denominator--
                if (denominator >= 1) { // 控制执行4次(分母从4到1)
                    handler.postDelayed(this, 3000)
                }
            }
        }
        handler.postDelayed(updateRunnable, 0) // 立即执行第一次更新
    }

    override fun onDestroy() {
        super.onDestroy()
        handler.removeCallbacksAndMessages(null) // 页面销毁时清理回调,防止内存泄漏
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 18:37:15