解释表
代码 | 比喻 | 作用 |
---|
Looper.prepare() | 搭建快递仓库 | 创建消息队列(MessageQueue) |
new Handler() | 雇佣快递员 | 绑定当前线程的 Looper,负责收发消息 |
Looper.loop() | 快递站开始运营 | 启动无限循环,不断从队列取消息处理 |
handler.sendMessage() | 往仓库放包裹 | 将消息放入队列 |
handleMessage() | 快递员处理包裹 | 收到消息时执行对应操作 |
Looper.quit() | 关闭快递站 | 停止消息循环(需在子线程需要退出时调用) |
- 主线程天生有快递站(自动创建 Looper)
- 子线程要自己建仓库(先调用
Looper.prepare()
) - 快递员必须绑定仓库(
new Handler()
必须在 prepare()
之后) - 开张才能处理包裹(必须调用
Looper.loop()
)
场景 | 代码示例 | 说明 |
---|
子线程更新 UI | new Handler(Looper.getMainLooper()) | 让主线程执行界面操作 |
定时任务 | Handler(Looper.getMainLooper()).postDelayed() | 在主线程延迟执行 |
防止内存泄漏 | 配合 WeakReference ,避免持 Activity 引用 | 安全地操作主线程的 UI |
常见问题
Q:主线程调用 Looper.getMainLooper()
会得到什么?
- 主线程默认已有
Looper
,因此会返回自身的 Looper
,等同于直接调用 new Handler()
。
Q:为什么子线程不直接用 new Handler()
?
- 子线程默认没有
Looper
,必须手动调用 Looper.prepare()
+ Looper.loop()
。想通主线程发任务时,必须指定主线程的 Looper
。
技术原理总结
术语 | 作用 |
---|
Looper | 消息循环管理者,每个线程最多一个。主线程的 Looper 存在于整个应用生命周期。 |
getMainLooper() | 静态方法,全局获取主线程的 Looper。 |
主线程 Activity | 自带一个运行中的 Looper,由系统自动创建。 |
Handler 是“传话员”:把子线程的任务结果“告诉”主线程,让主线程去更新界面。
// 子线程中通过 Handler 更新 UI
new Thread(() -> {String data = downloadData(); // 耗时操作new Handler(Looper.getMainLooper()).post(() -> {textView.setText(data); // 主线程更新 UI});
}).start();
123
// 5秒后执行任务
new Handler(Looper.getMainLooper()).postDelayed(() -> {startActivity(new Intent(this, NextActivity.class));
}, 5000);
Looper 是“循环传送带”:持续从消息队列中取出任务,交给 Handler 处理。
// 步骤1:创建 Handler(快递员)
Handler handler = new Handler(Looper.getMainLooper()) {@Overridepublic void handleMessage(Message msg) {// 步骤4:处理消息(拆包裹)if (msg.what == 100) {Toast.makeText(MainActivity.this, (String) msg.obj, Toast.LENGTH_SHORT).show();}}
};// 步骤2:获取消息对象(拿空包裹)
Message message = handler.obtainMessage();
message.what = 100; // 消息类型
message.obj = "任务完成"; // 包裹内容// 步骤3:发送消息(派送包裹)
handler.sendMessage(message);
方法 | 比喻 | 使用场景 | 是否需手动调用 |
---|
handleMessage() | 拆包裹并执行任务 | 接收并处理消息 | 自动调用(需重写) |
obtainMessage() | 领取空包裹 | 需要发送消息时 | 手动调用 |
sendMessage() | 派送包裹 | 将消息发送到目标 Handler | 手动调用 |
5. 常见问题
Q:为什么用 obtainMessage()
而不是 new Message()
?
Q:sendMessage()
和 post()
有什么区别?