什么是
- Handler 类是处理线程间通信和任务调度的一个重要工具,用于在不同的线程之间传递消息和执行任务
使用场景
-
线程间通信:在子线程中执行任务后,更新主线程(UI 线程)的界面。
-
任务调度:安排在将来某个时间点执行的任务。
基本工作原理
-
消息队列:每个线程(包括主线程)都有一个消息队列。Handler 用来将消息或任务(称为 "消息" 或 "可运行任务")放入这个队列
-
消息处理:Handler 通过一个 Looper 对象来处理消息队列中的消息。主线程有一个默认的 Looper,而子线程需要显式创建一个 Looper 对象
Handler 的使用
-
创建 Handler 对象
Handler handler = new Handler();
- 这将创建一个与当前线程的 Looper 关联的 Handler。在主线程中,默认的 Looper 是主线程的 Looper,所以这个 Handler 会处理主线程的消息队列
-
发送消息
Message msg = handler.obtainMessage(); msg.what = 1; // 设置消息类型 handler.sendMessage(msg); // 发送消息
-
发送可运行任务
Runnable runnable = new Runnable() { @Override public void run() { // 这里写你的任务代码 } }; handler.post(runnable); // 立即执行 handler.postDelayed(runnable, 1000); // 1秒后执行
-
处理消息:需要实现 Handler 类的
handleMessage(Message msg)
方法。如果你不重写这个方法,Handler 会使用默认的处理逻辑Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case 1: // 处理消息类型 1 break; case 2: // 处理消息类型 2 break; } } };
线程与 Handler
-
主线程:通常用于更新 UI。可以直接创建 Handler 对象并处理 UI 相关的任务
-
子线程:需要显式创建 Looper。子线程不能直接更新 UI,所以通常会使用 Handler 将结果传递回主线程
// 在子线程中创建 Handler
Looper.prepare(); // 创建 Looper
Handler handler = new Handler(); // 创建 Handler
Looper.loop(); // 启动消息循环
常见应用场景
-
UI 更新:从子线程更新主线程的 UI 组件
-
定时任务:安排定时执行的任务
-
延迟任务:安排稍后执行的任务
代码示例
-
假设在子线程中执行一些任务,并在任务完成后更新主线程的 UI
// 主线程中的 Handler Handler mainHandler = new Handler(Looper.getMainLooper()); new Thread(new Runnable() { @Override public void run() { // 在子线程中执行任务 try { Thread.sleep(2000); // 模拟长时间任务 } catch (InterruptedException e) { e.printStackTrace(); } // 更新 UI 需要在主线程中进行 mainHandler.post(new Runnable() { @Override public void run() { // 更新 UI textView.setText("Task completed!"); } }); } }).start();
总结
-
Handler 用于线程间通信和任务调度
-
它通过消息队列和 Looper 来管理和处理消息
-
可以发送消息或可运行任务,并自定义消息处理逻辑
-
在主线程和子线程中都可以使用 Handler,但子线程需要创建自己的 Looper