外观
为什么不能在子线程中直接更新 UI?Handler 是如何解决这个问题的?
标准回答
大多数 View 状态由主线程统一管理,避免多个线程同时改同一界面。Handler 可以把结果送回这个线程。
- 常规 Activity 界面属于主线程,状态和绘制应遵守单线程约束。
- 后台线程负责 IO 或计算,结果通过主线程 Handler 应用到 View。
- 绑定 Looper.getMainLooper,避免误绑定当前子线程。
通俗例子
后台线程下载完成后,向主线程 Handler post 一个更新文字的任务。下载在后台,setText 在主线程执行。
深入解释
**为什么统一到主线程:**View 的内部状态与测量、布局、绘制会一起变化,多线程同时修改容易互相覆盖或读到不一致状态。Android 的常规界面操作因此由主线程统一处理。
**一个完整的做法:**后台完成网络或计算后,把纯结果传回主线程;主线程先确认页面仍有效,再更新 View。不要把整个下载过程一起 post 回去。
示例代码
java
Handler main = new Handler(Looper.getMainLooper());
executor.execute(() -> {
Result result = loadData();
main.post(() -> render(result));
});易混淆点
不是所有越线程访问都会立刻报错;偶尔没崩也不能证明线程安全。
参考资料
内容来源
- Android · AI Agent 知识手册 · 原条目
4.1.2