昨天研究了一下Handler的源码,今天总结一下:
android只有一个线程可以操作UI界面,我们称之为UI线程。
每个UI线程都维护一个looper,这个looper中有一个messagequeue来保存UI一个消息队列。通过控制这个消息队列来实现对UI界面的顺序刷新。
handler.sendMessage();
public final boolean sendMessage(Message msg)
{
return sendMessageDelayed(msg, 0);
}
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(Message msg, long uptimeMillis)
{
boolean sent = false;
MessageQueue queue = mQueue;
if (queue != null) {
msg.target = this;
sent = queue.enqueueMessage(msg, uptimeMillis);//加入message到消息队列
}
else {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
}
return sent;
}
从以上代码我们可以得出一个结论,handler的所有sendMessage都是通过sendMessageAtTime来时实现的。关键的一行是queue.enqueueMessage这个方法。这里的queue是个messagequeue.
final boolean enqueueMessage(Message msg, long when) {
if (msg.when != 0) {
throw new AndroidRuntimeException(msg
+ " This message is already in use.");
}
if (msg.target == null && !mQuitAllowed) {
throw new RuntimeException("Main thread not allowed to quit");
}
synchronized (this) {
if (mQuiting) {
RuntimeException e = new RuntimeException(
msg.target + " sending message to a Handler on a dead thread");
Log.w("MessageQueue", e.getMessage(), e);
return false;
} else if (msg.target == null) {
mQuiting = true;
}
msg.when = when;
//Log.d("MessageQueue", "Enqueing: " + msg);
Message p = mMessages;
if (p == null || when == 0 || when < p.when) {
msg.next = p;
mMessages = msg;
this.notify();
} else {
Message prev = null;
while (p != null && p.when <= when) {
prev = p;
p = p.next;
}
msg.next = prev.next;
prev.next = msg;
this.notify();
}
}
return true;
}
以上代码可以看出,messagequeue本质上是一个链表,这个链表根据时间排序。这个链表其实就是一个消息队列。
剩下的就很简单了,取消息时只需要从这个消息队列中依次取得即可。
删除消息时,只需要根据what从这个链表中摘除对应的消息即可。