MessageQueue内部实现,其实是一个单链表。从Message.java的源码中,可以看到类中有一个Message next;
的成员变量,说明Message是单链表的一个节点。
public final class Message implements Parcelable {
...
/*package*/ long when; //单链表排序的依据
...
/*package*/ Handler target; //保存Message是被哪个Handler发送的,谁发送的谁处理
/*package*/ Runnable callback; // 保存runOnUiThread()方法的入参Runnable
// sometimes we store linked lists of these things
/*package*/ Message next; //这是单链表节点的标志
...
}
既然MessageQueue是由单链表实现的,那MessageQueue中的Message入队采用的是头插法还是尾插法?
先说结论:有用到头插和尾插,但不是所有Message入队都用的头插法,也不是所有的Message入队都用尾插法。是根据成员变量when的数值大小来排序,找到合适的位置插入。
Message里的成员变量when的含义是什么?
单链表根据when
排序。when的值是在Handler.java的sendMessageDelayed()方法中生成的。
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
SystemClock.uptimeMillis()
是个什么鬼?
SystemClock是Android SDK提供的,路径是/frameworks/base/core/java/android/os/SystemClock.java,这个方法表示的是从开机到现在时间总数,单位是毫秒。另外一个方法,JDK中常用的,获取当前时间:System.currentTimeMillis()
,它获取的是从1970年1月1日 00:00:00 GMT
(Greenwich Mean Time, 格林威治时间,它规定太阳每天经过位于英国伦敦郊区的皇家格林威治天文台的时间为中午12点)
到现在的毫秒数,注意不是北京时间。关于这个System.currentTimeMillis()
,我有专门的文章探讨。
when=开机到现在的总时间+延迟时间。单位是毫秒。
System.currentTimeMillis()与SystemClock.uptimeMillis()
Android消息机制—MessageQuene插入和读取算法