Android Handler的使用

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操作。 创建方式:

  1. 在activity、service等组件里面直接构造Handler(无参构造),默认绑定主线程Looper。
  2. 显式传递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);
    }
}