public final class Message implements Parcelable{
Handler target;//target处理
Runnable callback;//Runnable类型的callback
Message next;//下一条消息,消息队列是链式存储的
//代码省略
}
至于Handler是如何关联消息队列以及线程的呢,我们可以从下面的代码中获悉,Handler在内部通过Looper.myLooper()来获取Looper对象,并且与之关联,获取消息队列。
public Handler(Callback callback, boolean async) {
// 仅贴出关键代码
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
“Can’t create handler inside thread that has not called Looper.prepare()”);
}
mQueue = mLooper.mQueue;
mCallback=null;
}
再看下面的代码,myLooper()方法返回的是sThreadLocal.get(),sThreadLocal是当前的线程,在prepareMainLooper()方法中prepare()将Looper对象放进了sThreadLocal中。
public static void prepare() {
prepare(true);
}
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {//每个线程只能有一个looper
throw new RuntimeException(“Only one Looper may be created per thread”);
}
//设置本线程的looper。
sThreadLocal.set(new Looper(quitAllowed));
}
所以最终,创建Handler的同时则自动在当前线程sThreadLocal中设置Looper对象,并获取该对象,进而获取消息队列。这样一来,Handler自然和消息队列以及线程关联起来了。
Looper通过loop()方法建立消息循环:
public static void loop() {
//里面调用了sThreadLocal.get()获得刚才创建的Looper对象
final Looper me = myLooper();
if (me == null) {//如果Looper为空则会抛出异常
throw new RuntimeException(“No Looper; Looper.prepare() wasn’t called on this thread.”);
}
final MessageQueue queue = me.mQueue;
for (;😉 {
//这是一个死循环,从消息队列不断的取消息
Message msg = queue.next(); // might block
if (msg == null) {
//由于刚创建MessageQueue就开始轮询,队列里是没有消息的,等到Handler sendMessage enqueueMessage 后队列里才有消息
return;
}
msg.target.dispatchMessage(msg);
}
}
在上面的loop方法中,我们看到通过dispatchMessage方法来处理消息,根据适才看过的Message代码,target是Handler类型,所以说,Handler将消息投递到消息队列后,消息队列有将消息分发给Handler来处理。我们来看看消息处理函数的具体实现:
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
//callback在message的构造方法中初始化或者使用handler.post(Runnable)