Android 之Handler原理解析

47 阅读2分钟

Handler类概述

Handler类位于android.os包中,它允许你发送和处理MessageRunnable对象。Handler通常与LooperMessageQueue一起工作,Looper用于循环检查消息队列(MessageQueue),而Handler则用于将消息发送到这个消息队列。

基本用法

  1. 创建Handler实例

    Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            // 处理消息
            return true;
        }
    });
    
  2. 发送消息

    Message message = Message.obtain(); // 获取一个Message实例
    message.what = 0; // 设置消息的what字段,用于标识消息类型
    handler.sendMessage(message); // 发送消息
    
  3. 发送Runnable

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            // 在这里执行任务
        }
    };
    handler.post(runnable); // 将Runnable发送到消息队列
    

代码解析

以下是Handler类的一些关键部分的代码解析:

public class Handler {
    final Looper mLooper; // 与Handler关联的Looper
    final MessageQueue mQueue; // 消息队列
    final Callback mCallback; // 处理消息的回调

    public Handler(Callback callback) {
        mLooper = Looper.myLooper(); // 获取当前线程的Looper
        mQueue = MessageQueue(); // 获取消息队列
        mCallback = callback; // 设置消息处理回调
    }

    public final void sendMessage(Message msg) {
        if (msg == null) {
            throw new IllegalArgumentException("msg == null");
        }
        if (mLooper == null) {
            throw new IllegalStateException("Can't send messages to a Handler that hasn't been looper");
        }
        msg.target = this; // 设置消息的目标为当前Handler
        mQueue.enqueueMessage(msg); // 将消息放入消息队列
    }

    public final boolean handleMessage(Message msg) {
        return mCallback != null && mCallback.handleMessage(msg);
    }
}

工作流程

  1. 创建Handler:首先创建一个Handler实例,可以指定一个Callback来处理消息。

  2. 发送消息:通过sendMessage()方法发送Message对象到消息队列。

  3. 消息处理Looper循环检查消息队列,当发现新消息时,通过handleMessage()方法将消息传递给Handler

  4. 执行任务:如果发送的是Runnable,它会被封装成一个Message,然后按照同样的方式处理。

注意事项

  • Handler是线程相关的,它与创建它的线程的LooperMessageQueue关联。
  • 在非UI线程中使用Handler时,需要确保该线程有Looper(可以通过Looper.prepare()Looper.loop()设置)。
  • 使用post()方法可以延迟执行Runnable,而sendMessage()可以发送消息并可能携带数据。