runOnUiThread报错致App崩溃,求修复非UI线程无障碍内容变更问题
问题修复方案
错误原因分析
- UI线程被阻塞:
refresh方法本身运行在UI线程(按钮点击回调默认在UI线程),你在runOnUiThread的Runnable里调用了Thread.sleep(5000),这会直接阻塞UI线程,导致应用无响应甚至崩溃。 - 不必要的UI线程调度:循环中连续向UI线程post12个任务,每个任务都阻塞5秒,完全占用了UI线程,无法处理其他界面事件。
- 非UI操作占用UI线程:内存状态计算属于非UI操作,放在UI线程会额外消耗UI线程资源。
修复后的代码
Java代码
package com.tools.cpuusage; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.ProgressBar; public class MainActivity2 extends AppCompatActivity { private ProgressBar[] progressBars; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); // 用数组存储ProgressBar,简化后续操作 progressBars = new ProgressBar[]{ findViewById(R.id.progressBar1), findViewById(R.id.progressBar2), findViewById(R.id.progressBar3), findViewById(R.id.progressBar4), findViewById(R.id.progressBar5), findViewById(R.id.progressBar6), findViewById(R.id.progressBar7), findViewById(R.id.progressBar8), findViewById(R.id.progressBar9), findViewById(R.id.progressBar10), findViewById(R.id.progressBar11), findViewById(R.id.progressBar12) }; } public void refresh(View view) { // 启动后台线程处理循环和延迟,避免阻塞UI new Thread(() -> { int accuracy = 100; for (int c = 0; c < 12; c++) { int finalC = c; // 计算内存状态,放在后台线程 int memory = (int) ((double) accuracy * ((double)(Runtime.getRuntime().freeMemory() / (1024 * 1024)) / (double)(Runtime.getRuntime().totalMemory() / (1024 * 1024)))); // 仅更新UI时切换到UI线程 runOnUiThread(() -> { if (finalC == 0) { progressBars[finalC].setProgress(0); } else if (finalC <= 3) { progressBars[finalC].setProgress(78); } else { progressBars[finalC].setProgress(memory); } }); // 在后台线程执行延迟,不阻塞UI try { Thread.sleep(5000); } catch (InterruptedException ignore) {} } }).start(); } }
关键优化点
- 后台线程处理耗时逻辑:将循环、延迟、内存计算都放在后台线程,仅在更新ProgressBar时切换到UI线程。
- 数组存储控件引用:替换大量if-else判断,简化代码逻辑。
- 解除UI线程阻塞:将
Thread.sleep移到后台线程,保证UI线程始终能响应用户操作。
额外建议
- 如果需要定期刷新内存状态,推荐使用
Handler或协程(Kotlin)实现定时任务,比手动管理线程更稳定。 - 可以给ProgressBar设置最大进度(
setMax(100)),确保进度值在合理范围内。
内容的提问来源于stack exchange,提问作者Betu Raja
相关产品推荐
相关产品推荐

