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

Android应用ProgressBar在循环中进度不更新问题求助

解决ProgressBar在循环内不更新的问题

嘿,我看了你的代码,问题其实出在Android UI线程的规则上,还有几处小细节没处理到位,导致ProgressBar没按预期更新。

问题根源

  1. 非主线程直接操作UI:你在子线程里直接执行了progressBar!!.progress = i和progressBar!!.visibility = View.INVISIBLE这两行代码。Android明确要求所有UI更新操作必须在主线程执行,虽然这种操作不会立刻崩溃,但会导致UI更新失效——这就是你日志能看到i变化,但界面没反应的核心原因。
  2. 变量初始化逻辑瑕疵:你先把progressBar!!.progress赋值给了i,紧接着又把progressBar的进度设为0,但i并没有同步改为0——不过这个在你的场景里影响不大,只是逻辑不够严谨。

修正后的代码(Thread+Handler版本)

我把所有UI操作都移到了handler.post()里,同时修正了i的初始化逻辑,还优化了非空调用的安全性:

class StartActivity : AppCompatActivity() {
    private var progressBar: ProgressBar? = null
    private val handler = Handler(Looper.getMainLooper()) // 明确指定主线程Looper,更严谨

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_start)
        progressBar = findViewById<ProgressBar>(R.id.progressBar_activityStart)
        startProgressBar()
    }

    private fun startProgressBar() {
        progressBar?.visibility = View.VISIBLE
        progressBar?.progress = 0
        var i = 0 // 直接从0开始,逻辑更清晰
        Thread {
            while (i < 100) {
                i += 1
                // 所有UI更新都通过Handler提交到主线程
                handler.post {
                    progressBar?.progress = i
                    Log.v("progress", i.toString())
                }
                try {
                    Thread.sleep(100)
                } catch (e: InterruptedException) {
                    e.printStackTrace()
                }
            }
            // 隐藏ProgressBar也要放到主线程执行
            handler.post {
                progressBar?.visibility = View.INVISIBLE
            }
        }.start()
    }
}

更简洁的方案:使用Kotlin协程(推荐)

如果你的项目已经引入了协程依赖,用协程来实现会更简洁,不需要手动管理Thread和Handler,代码可读性也更高:

class StartActivity : AppCompatActivity() {
    private var progressBar: ProgressBar? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_start)
        progressBar = findViewById<ProgressBar>(R.id.progressBar_activityStart)
        startProgressBar()
    }

    private fun startProgressBar() = lifecycleScope.launch {
        progressBar?.visibility = View.VISIBLE
        progressBar?.progress = 0
        for (i in 1..100) {
            progressBar?.progress = i
            Log.v("progress", i.toString())
            delay(100) // 协程的delay不会阻塞线程,比Thread.sleep更友好
        }
        progressBar?.visibility = View.INVISIBLE
    }
}

注意:要使用lifecycleScope需要确保你的项目依赖了androidx.lifecycle:lifecycle-runtime-ktx相关库。

额外小提醒

  • 尽量避免使用!!强制非空断言,换成?.安全调用更稳妥,能有效避免空指针异常。
  • 布局里的ProgressBar同时设置了android:layout_below和android:layout_alignBottom,这两个属性有冲突,建议只保留android:layout_below,让ProgressBar在logo下方正常显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 09:57:42