1. Looper
在讲Handler之前,首先要讲讲Looper和MessageQueue。
Looper类源码的说明:Looper是用来给线程发送消息的,线程没有默认的message loop,可以通过Looper.prepare()
创建线程的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));
}
Looper中有两个关键的属性:
- MessageQueue mQueue:消息队列,用来处理消息
- Looper sMainLooper:主线程的looper,也就是Android的UI线程本身就是有looper的,不需要手动去prepare
Looper类中的loop函数则用于具体的消息处理(只选取部分代码)
public static void loop() {
final Looper me = myLooper(); // 首先要有looper
final MessageQueue queue = me.mQueue;
// 死循环
for(;;) {
Message msg = queue.next(); // 没有要处理的信息时是阻塞的
if (msg == null) {
return; // 返回
}
// ... 计算消息的优先级,发送时间的代码
try {
msg.target.dispatchMessage(msg);
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
msg.recycleUnchecked(); // 回收消息
}
}
MessageQueue处理消息的代码暂时没能力看懂orz,自作聪明以为里面持有一个Message的队列,结果发现里面只有一个Message对象,每个Message对象都有next属性指向下一个Message
2. Handler
Looper也好,MessageQueue也好,怎么和Handler联系起来呢?
首先看看构造函数:
2.1 构造函数
public Handler(Looper looper, Callback callback) {
this(looper, callback, false);
}
也可以什么都不传参数或者只传其中一个,在调用链上都会使用到这个构造函数
2.2 sendMessage
sendMessage+后缀的一系列方法,最后都是调用sendMessageAtTime
这个方法
public boolean sendMessageAtTime(Message msg, long uptimeMills) {
MessageQueue queue = mQueue;
if (queue == null) {
// ...报错
return false;
}
return enqueueMessage(queue, msg, uptimeMills);
}
可以看到这里出现了上面提到的MessageQueue,而mQueue则是通过looper.mQueue
拿到的,也就是说如果自定义线程的Handler,必须传入Looper,否则会报错,而UI线程因为本来就持有looper对象可以直接创建。
enqueueMessage最终调用的是queue.enqueueMessage
,也就是把消息委派给MessageQueue去处理了
2.3 handleMessage
使用过Handler的人一定都知道handleMessage这个方法,它是用来处理我们自定义的消息。
Handler中两个handlerMessage方法,一个定义在内类接口Callback中,另一个是个空方法(匿名Handler类重写的就是这个方法)
public interface Callback {
public boolean handleMessage(Message msg);
}
public void handleMessage(Message msg) {
}
将这两者联系起来的是**dispatchMessage(Message msg)**这个方法
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
可以看到,调用的优先级:Message实现的Callback > Handler内的Callback > 自己实现Handler子类重写的handleMessage方法