学习笔记-安卓Handler

111 阅读3分钟

Android Handler 机制深度解析

1. Handler 机制的核心组件

1.1 Handler

  • 作用

    • 发送消息到 MessageQueue
    • 处理 Looper 分发的消息。
  • 关键方法

    public void handleMessage(@NonNull Message msg) {} // 需子类重写
    public final boolean sendMessage(@NonNull Message msg) {}
    public final boolean post(@NonNull Runnable r) {}
    

1.2 Looper

  • 作用

    • 通过死循环 (loop()) 从 MessageQueue 中取出消息。
    • 将消息分发给对应的 Handler
  • 核心代码

    public static void loop() {
        while (true) {
            Message msg = queue.next(); // 从 MessageQueue 取消息
            msg.target.dispatchMessage(msg); // 分发消息
        }
    }
    

1.3 MessageQueue

  • 作用

    • 存储消息的队列(链表结构)。
    • 管理线程休眠与唤醒(通过 nativePollOnce 和 nativeWake)。
  • 消息插入与取出

    • enqueueMessage():插入消息并按时间排序。
    • next():取出消息(无消息时线程休眠)。

1.4 Message

  • 结构

    public final class Message {
        Handler target;      // 目标 Handler
        Runnable callback;   // Runnable 任务
        Object obj;          // 携带的数据
        int what;            // 消息标识
        Message next;        // 链表结构的下一个消息
    }
    

2. 消息处理流程

2.1 发送消息

  • 通过 sendMessage

    Handler handler = new Handler();
    Message msg = handler.obtainMessage(1); // what = 1
    handler.sendMessage(msg);
    
  • 通过 post

    handler.post(() -> {
        // 执行任务
    });
    

2.2 消息分发

  • dispatchMessage() 的逻辑:

    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);  // 执行 Runnable
        } else if (mCallback != null) {
            mCallback.handleMessage(msg); // 全局 Callback 处理
        } else {
            handleMessage(msg);  // 子类处理
        }
    }
    

3. Thread.sleep() 与 interrupt() 的区别

特性Thread.sleep()Thread.interrupt()
作用让线程休眠指定时间设置线程中断状态
是否释放锁不释放锁不涉及锁
异常休眠时被中断会抛 InterruptedException中断阻塞操作会抛 InterruptedException
中断状态抛异常后清除中断状态直接设置中断状态

4. nativePollOnce 与 nativeWake 的作用

4.1 nativePollOnce

  • 功能:让线程进入低功耗休眠状态。
  • 实现:基于 epoll 监听文件描述符事件。
  • 场景:当 MessageQueue 为空时调用。

4.2 nativeWake

  • 功能:唤醒休眠的线程。
  • 场景:当新消息插入 MessageQueue 时调用。

4.3 对比 Thread.sleep()

特性nativePollOnceThread.sleep()
功耗低功耗(完全休眠)较高(定期唤醒)
响应速度事件驱动(快速响应)依赖定时器(较慢)
系统集成支持监听文件描述符事件仅支持定时休眠

5. 同步消息与异步消息

5.1 同步消息

  • 默认行为:按插入顺序处理。

  • 发送方式

    handler.sendMessage(msg);
    

5.2 异步消息

  • 标记方法

    msg.setAsynchronous(true);
    
  • 使用场景:需要优先处理的任务(如 UI 更新)。


6. post() 与 sendMessage() 的区别

特性post()sendMessage()
参数类型RunnableMessage
处理方式直接执行 Runnable.run()调用 handleMessage()
是否需要继承是(需重写 handleMessage()

7. 常见问题解答

7.1 为什么 post() 无法触发 handleMessage()

  • 原因post() 会将 Runnable 赋值给 Message.callback,而 dispatchMessage() 优先执行 callback
  • 解决方案:改用 sendMessage() 或结合两者使用。

7.2 runOnUiThread() 的原理是什么?

  • 源码

    public final void runOnUiThread(Runnable action) {
        if (isMainThread()) action.run();
        else mHandler.post(action);
    }
    
  • 本质:通过 Handler.post() 在主线程执行任务。

7.3 如何监听 post() 的消息?

  • 直接处理:在 Runnable 中实现逻辑。
  • 间接通知:在 Runnable 中发送 Message

总结

  • Handler 机制:基于生产者-消费者模型,实现线程间通信。
  • 核心设计:通过 nativePollOnce 和 nativeWake 优化性能与功耗。
  • 灵活使用:根据需求选择 post()(执行任务)或 sendMessage()(处理消息)。