在Android系统中,消息的发送和处理通过Handler和Looper机制来完成的。
Looper主要负责消息机制的运转,就像VC++中有一个循环列表,在不停的接受消息,然后分发消息,至于消息怎么发送和发送到哪里都是由Handler来决定的。
Handler主要是对外提供消息发送和接收的接口,就是sendMessage(Message msg),dispatchMessage(Message msg),handlerMessage(Message msg)这三个函数。
通过查看Handler和Looper的source code可以发现,这两个类中都维护了一个消息队列final MessageQueue mQueue;
而这个消息队列其实就是Hanlder和Looper进行通信的纽带,我们可以简单的理解为:
当调用sendMessage函数时,其实是向消息队列添加了一条消息。
当调用dispatchMessage函数时,其实是从消息队列中取出了一条消息进行处理。
而Looper则启动了一个循环,在不停的检测有没有消息到了,如果有消息到来就调用Handler的dispatchMessage函数进行处理。
这样理解,我们就可以不用去管Handler和Looper的内部处理过程有多么的复杂,只需关注这两个消息发送和处理函数即可,在阅读代码的时候,也不用费很大力气去定位或查找消息的处理函数。
2. dispatchMessage ---- 消息处理函数,不用外部进行显式的调用,Looper会在收到消息的时候会自动调用,进行消息处理。
查看dispatchMessage的源码发现,在调用handler的dispatchMessage函数时,根据不同的条件会调用不同的函数,而且也有优先级:
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
private final void handleCallback(Message message) {
message.callback.run();
}
1. 如果msg.callback != null,则执行handleCallback(msg);
那么msg.callback是在什么时候赋值的呢?
两个函数会对msg.callback进行赋值:
1)public static Message obtain(Message orig) {
Message m = obtain();
m.what = orig.what;
m.arg1 = orig.arg1;
m.arg2 = orig.arg2;
m.obj = orig.obj;
m.replyTo = orig.replyTo;
if (orig.data != null) {
m.data = new Bundle(orig.data);
}
m.target = orig.target;
m.callback = orig.callback;
return m;
}
2)public static Message obtain(Handler h, Runnable callback) {
Message m = obtain();
m.target = h;
m.callback = callback;
return m;
}
所以在查看消息处理对应的函数时,一定要查看在构造消息的时候有没有调用以上两个函数中的一个,
如果调用了,那么消息处理就会交由传递参数中message.callback.run()来处理。
2. 如果msg.callback == null,且mCallback != null,则由mCallback.handleMessage()来处理。
那么mCallback是在什么时候赋值的呢?
1). public Handler(Callback callback) {
.................
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 = callback;
}
2). public Handler(Looper looper, Callback callback) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
}
3. 如果msg.callback == null,且mCallback == null,则由Handler自身的handleMessage()来处理。
总之,在判断调用哪个消息处理函数时,一定要先看是否在调用obtain构造消息的时候是不是传递了msg或Runable参数,如果没有,则判断在构造Handler时是否将Callback函数当作参数传递了进来,最后再看自己的Handler是否重写了handleMessage函数。