官方描述
Handle通过线程的MessageQueue发送和处理Message和Runnable对象,每一个Handle实例和一个单例的Thread及它的MessageQueue相关联。
创建一个Handle的时候,他就绑定到线程及对应的MessageQueue,此后,Handle将会处理Message,把Message发送到MessageQueue,并且处理
从MessageQueue里出来的Message。Handle主要有两个作用:定时处理Message;把不同线程Action排队。通过不同的方法,可以马上执行也可以
延后执行。当app创建的时候(一个进程),主线程创建一个MessageQueue专门处理顶级对象(Activity、broadcast等)及其他Window相关对象。
开发者可以在新建的线程通过Handle与主线程交流。
相关关键人物
- Handler
发送及调整Message时机,取得与当前线程一致的Looper并循环,把Message压入MessageQueue。最终处理Message - Message
中间流通的消息,携带处理方及自身属性 - Looper
循环,当MessageQueue里的消息到时的时候,取出Message,并通过Message的target把处理逻辑回到Handle - MessageQueue
Message的队列,排序里边的Message,适当的时候取出来。消息不会直接添加到MessageQueue中,而是通过与Looper关联的{@link Handler}对象
源码分析
- 创建handler时,初始化了handler内的looper、MessageQueue、callback
public Handler(@Nullable Callback callback, boolean async) {
.....
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread " + Thread.currentThread()
+ " that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
- 创造消息
这里刚开始sPool 为空,后边就开始复用了
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
return new Message();
}
- 发送消息最终调用方法
public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
- 准备开始去MessageQueue里排队,排队前把自身(handler)给了Message的target,这也为Handler内存泄露埋下了伏笔
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
long uptimeMillis) {
msg.target = this;
msg.workSourceUid = ThreadLocalWorkSource.getUid();
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
- looper.loop()发动,
// sThreadLocal.get() will return null unless you've called prepare().
@UnsupportedAppUsage
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
/**
* Return the Looper object associated with the current thread. Returns
* null if the calling thread is not associated with a Looper.
*/
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
try {
// msg.target=handler
msg.target.dispatchMessage(msg);
} catch (Exception exception) {
} finally {
}
msg.recycleUnchecked();
}
}
- 再次回到Handler里
/**
* Handle system messages here.
*/
public void dispatchMessage(@NonNull Message msg) {
if (msg.callback != null) {
// 一般情况为空,除非创建Message的时候设置或者用Handle的post
handleCallback(msg);
} else {
if (mCallback != null) {
// 一般情况下我们用handler的无参构造函数,所以这里大多情况也为空
if (mCallback.handleMessage(msg)) {
return;
}
}
// 这里便是我们创建handler之后,重新的那个
handleMessage(msg);
}
}
消息处理流程
- 首先创建Handle,并实现handleMessage,默认创建的Handle的变量callback是空
- handle发送消息,最终调用sendMessageAtTime
- 当前handle对象赋给当前Message的target变量
- 排队。。。
- Looper.loop,looper里有个MessageQueue,取出下一个最近的Message,调用Message的target的dispatchMessage方法,
- 如果handle是调用的post,则post时的入参runnable赋给Message的callback(Runnable),否则Message的callback就是null
- 最终回调给Handle的是
- 如果Message的callback不为空,则有post时候的runnable的run方法接收
- 如果Handle的callback不为空,则有创建Handle时候的callback的handleMessage接收
- 以上都为空,则调用自己实现的handleMessage接收