在使用Handler时可能遇到一些疑问,handler.post(Runnable r)中的run()方法与handleMessage()的调用
Handler.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
}
});
public interface Callback {
public boolean handleMessage(Message msg);
}
post调用了sendMessageDelayed
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
handler发送消息最终都会调用sendMessageAtTime
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
//注意下面这行代码
return enqueueMessage(queue, msg, uptimeMillis);
}
该方法内部调用了enqueueMessage方法,该方法的源码如下:
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
//注意下面这行代码
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
//注意下面这行代码
return queue.enqueueMessage(msg, uptimeMillis);
}
在该方法中有两件事需要注意:
- msg.target = this
该代码将Message的target绑定为当前的Handler - queue.enqueueMessage
变量queue表示的是Handler所绑定的消息队列MessageQueue,通过调用queue.enqueueMessage(msg, uptimeMillis)我们将Message放入到消息队列中。
我们在分析Looper.loop()的源码时发现,Looper一直在不断的从消息队列中通过MessageQueue的next方法获取Message,然后通过代码msg.target.dispatchMessage(msg)让该msg所绑定的Handler(Message.target)执行dispatchMessage方法以实现对Message的处理。
Handler的dispatchMessage的源码如下:
public void dispatchMessage(Message msg) {
//注意下面这行代码
if (msg.callback != null) {
handleCallback(msg);
} else {
//注意下面这行代码
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
//注意下面这行代码
handleMessage(msg);
}
}
看见这里的handleCallback(msg)了吗?这里会判断msg.callback != null,之后调用如下代码:
private static void handleCallback(Message message) {
message.callback.run();
}
这样我们我们就清楚地看到我们执行了msg.callback的run方法,也就是执行了postXXX所传递的Runnable对象的run方法。
上面的代码的出来一个结论:如果我们不是通过postXXX系列方法将Message放入到消息队列中的,那么msg.callback就是null,代码继续往下执行,接着我们会判断Handler的成员字段mCallback存不存在。mCallback是Hanlder.Callback类型的,我们在上面提到过,在Handler的构造函数中我们可以传递Hanlder.Callback类型的对象,该对象需要实现handleMessage方法,如果我们在构造函数中传递了该Callback对象,那么我们就会让Callback的handleMessage方法来处理Message。