本文是专门分析Handler的post()方法,将一个任务丢到主线程的流程分析,阅读本文需要对Handler有一定的了解(起码要了解Handler是如何进行线程切换的);
话不多说,直接开撕(目录不要了,提纲也不要了,今天旅长来了也得手撕)!!!
先看post()方法
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
发现其还是调用的发送消息一样的方法,这个过程熟悉Handler代码的人都知道,就不做详细的分析了,主要的代码还是这个getPostMessage(r)
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
查看源码发现,其就是给Message的成员变量callback进行赋值,然后什么都不做,是的什么都没做
接下来就是Handler的执行流程:
- 正常的sendMessage(),
- 调用了MessageQueue的enqueueMessage()方法将Message存放到MessageQueue内,
- 由Looper去取到该消息,
- 并回调会Handler里面(通过Message上的target成员变量找到发送消息的Handler对象并执行disptachMessage()方法) (这里说一下我对Handler切换线程的理解,无论我们发送Message在哪一个线程,Looper对应的线程是MainThread,Looper去取出消息并将这个消息回调给Handler的线程都是主线程)
回调到Handler这里,找到dispatchMessage()方法
发现如果Message上的callback成员变量不是null,则执行handleCallback(msg)方法, 否则查看Handler在创建的时候又没有赋值mCallback,如果有则只会这个回调的handleMessage()方法,没有的话就执行Handler的handleMessage()方法
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
重点在于执行handleCallback()方法,他拿着这个callback直接调用了run()方法(就这样切换回了主线程)
private static void handleCallback(Message message) {
message.callback.run();
}
对线程熟悉的程序员们应该就懂了,我们设置了一个Runnable,但是到最后发现没有给其塞到Thread里面并start这个Thread去执行run()方法,而是直接通过对象调用方法的方式,直接执行的run()方法。