美文网首页
Handler、Looper与MessageQueue之间的关系

Handler、Looper与MessageQueue之间的关系

作者: 锦岳 | 来源:发表于2020-07-28 17:16 被阅读0次
  • Handler 封装了消息的发送,也负责接收消息,内部会与Looper 关联
  • Looper封装了线程中的消息循环,内部包含了MessageQueue,负责从MessageQueue取出消息,然后交给Handler 处理
  • MessageQueue就是一个消息队列,负责存储消息,收到消息就存储起来,Looper会循环从MessageQueue读取消息

  1. Handler
public Handler(Callback callback, boolean async) {
    // ...
    mLooper = Looper.myLooper();
    // ...
    mQueue = mLooper.mQueue;
    mCallback = callback;
    mAsynchronous = async;
}
  1. Looper.myLooper()
public static @Nullable Looper myLooper() {
    return sThreadLocal.get();
}

sThreadLocal 是一个 ThreadLocal 对象,可以在一个线程中存储变量。底层是 ThreadLocalMap(一个Map类型)

  1. ActivityThread.main()

ActivityThread 是 Android App进程的初始类,main函数是App进程的入口。

public static final void main(String[] args) {
    Looper.prepareMainLooper();
    if(sMainThreadHandler == null) {
        sMainThreadHandler = new Handler();
    }

    ActivityThread thread = new ActivityThread();
    thread.attach(false);

    if(false) {
        Looper.myLooper().sendMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
    }

    Looper.loop();
}
  1. Looper.prepareMainLooper()
public static void prepareMainLooper() {
    prepare(false);
    synchronized (Looper.class) {
        if(sMainLooper != null) {
            throw new IllegalStateException("The main Looper has already been prepared.");
        }
        sMainLooper = myLooper();
    }
}

该方法会新建一个 Looper 对象并存储在 sThreadLocal 中。

  1. Looper.prepare()
private static void prepare(boolean quitAllowed) {
    if(sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    sThreadLocal.set(new Looper(quitAllowed));
}
  1. Looper 构造器
private Looper(boolean quitAllowed) {
    mQueue = new MessageQueue(quitAllowed);
    mThread = Thread.currentThread();
}
  1. Looper.loop()

该方法是一个死循环,会一直从 MessageQueue 中获取消息。如果获取到消息,就会执行 msg.target.dispatchMessage(msg),其中 msg.target 就是 Handler 对象,也就是调用 Handler 的 dispatchMessage() 方法,然后将从 MessageQueue 中获取的消息传入。

  1. Handler.dispatchMessage() 方法

dispatchMessage() 方法对消息进行最后的处理,如果是 post 类型,就调用 handlerCallback 方法处理,否则是 sendMessage 发送的消息。先查看是否有拦截,如果没有,最终就调用 handlerMessage 方法进行处理。


public void dispatchMessage(Message msg) {
    // 如果 callback 不为空,说明发送消息时是发送一个 Runnable 对象
    if(msg.callback != null) {
        handleCallback(msg);
    } else {
        if(mCallback != null) { // 这是用来拦截消息的
            if(mCallback.handleMessage(msg)) {
                return;
            }
        }
        handleMessage(msg); // 最终调用重写的 handleMessage() 方法
    }
}

  1. Handler.handleCallback()
private static void handleCallback(Message msg) {
    msg.callback.run();
}

相关文章

网友评论

      本文标题:Handler、Looper与MessageQueue之间的关系

      本文链接:https://www.haomeiwen.com/subject/ikfqrktx.html