1.描述
本文主要是快速记录一下Handler的使用,大体了解一下Handler类,使用该类监听来自其它线程的消息。 通过这种方式,实现类间的线程安全通信,尤其适合需要跨线程更新UI或者执行异步任务的场景。
2.流程
主要使用流程,创建Handler类,重写,调用。详细:
2.1 定义Handler类
在类中创建Handler实例,重写handleMessage方法
2.2 发送消息
其它线程通过该Handler发送消息
2.3 处理消息
Handler在其绑定的线程中调用handleMessage处理消息。
3.注意事项
在类中创建Handler本身不创建新线程,它只是用于在已有线程中处理消息,Handler的行为取决于 创建它时所绑定的线程。
3.1 绑定到主线程中(UI线程)
这个Handler的handleMessage()方法会在UI线程中执行,用于更新UI操作。 创建方式:
- 在activity、service等组件里面直接构造Handler(无参构造),默认绑定主线程Looper。
- 显式传递Looper.getMainLooper()
3.2 绑定到子线程
需要在子线程中手动初始化Looper,在创建Handler绑定该子线程Looper,
这个Handler的handleMessage()方法会在当前子线程中执行,适合后台耗时操作。
public class MyClass { // 在子线程中初始化 Handler public void initHandlerInSubThread() { new Thread(() -> { Looper.prepare(); // 子线程必须先调用 prepare() Handler subHandler = new Handler(Looper.myLooper()) { @Override public void handleMessage(Message msg) { // 在子线程中处理消息 } }; Looper.loop(); // 启动子线程的消息循环 }).start(); } }
4.误区理解
Handler必须依赖已有的Looper(属于某个线程),自身不创建线程。 Handler.sendEmptyMessage() 或 Handler.post(Runnable) 只是将任务加入 目标线程的消息队列(MessageQueue), 由目标线程的 Looper 循环执行,不会创建新线程。 参考例子:
public class DataLoader {
private Handler mainHandler; // 绑定主线程,用于更新 UI
private Handler workerHandler; // 绑定子线程,用于后台加载数据
public DataLoader(Context context) {
// 初始化主线程 Handler(用于接收子线程结果并更新 UI)
mainHandler = new Handler(Looper.getMainLooper());
// 启动子线程并初始化 Worker Handler
new Thread(() -> {
Looper.prepare();
workerHandler = new Handler(Looper.myLooper()) {
@Override
public void handleMessage(Message msg) {
if (msg.what == MSG_LOAD_DATA) {
String data = loadDataFromNetwork(); // 子线程执行耗时操作
// 将结果发送到主线程 Handler
mainHandler.obtainMessage(MSG_UPDATE_UI, data).sendToTarget();
}
}
};
Looper.loop();
}).start();
}
// 外部调用:触发子线程加载数据
public void loadData() {
workerHandler.sendEmptyMessage(MSG_LOAD_DATA); // 向子线程发送消息
}
// 主线程回调接口(供 Activity 实现)
public interface DataCallback {
void onDataLoaded(String data);
}
}
您还没有登录,请您登录后发表评论。