一、Message
1.Field
public int what; //message code
public int arg1;
public int arg2;
public Object obj;
long when; //消息何时执行,是否延迟
Handler target; //
Runnable callback; //
Message next; //消息链,单向链表结构
private static final Object sPoolSync = new Object();
private static Message sPool; //缓存池,采用了单向链表的方式
private static int sPoolSize; //池中消息的数量
2.Method
public static Message obtain() {
synchronized(sPoolSync) {
if(sPool != null) {
Message m = sPool;
//从消息池中取出一个已用过的消息对象,达到对象复用
sPool = m.next;
//注意这里取出的是链表头
m.next = null;
sPoolSize--;
return m;
}
}
return new Message();
}
public void recycle() {
clearForRecycle();
synchronized(sPoolSync) {
if(sPoolSize < MAX_POOL_SIZE) {
next = sPool;
//每次Message被用过后,都将已用过的消息放到链表头里面,
sPool = this;
//如果缓存池数量已达最大限制,则不缓存
sPoolSize++;
}
}
}
Message里有一个缓存池,采用了一个单向链表来存储所有已经用过的消息,每次构造Message对象时,最优的方式是直接调用obtain()方法来获取缓存对象。
二、MessageQueue
1.Field:
Message
mMessages;
顾名思义,第一感觉内部应该有个队列queue,比方说用List、Array、Map等来存储,但这里只有一个Message对象,那它使怎么存储这个队列的呢?
由前面可以看到,Message其实在内部定义了个单向的链表结构,所以在MessageQueue里只需要记住这个链表的表头就可以了。
2.Method:
final Message next()
final void quit();
final boolean enqueueMessage(Message msg, long when) {
……
…...
Message p = mMessage; //获取链表头的message消息对象
//如果消息池里消息为空,或者该消息响应的时间已过,或者链表头的消息大于该消息的时间
//则将该消息放在表头,相当于会立马执行
if(p == null || when == 0 || when < p.when) {
msg.next = p;
mMessage = msg;
…...
} else {
……
Message prev;
for( ; ; ) {
//遍历单向链表
prev = p;
p = p.next;
if(p == null || when < p.when) {
break;
}
…...
}
msg.next = p;
prev.next = msg;
//根据Message要执行的时间,按从小到大进行排序,把该消息插入到
//链表当中对应的位置
}
……
…...
}
在MessageQueue中将message加入队列的过程,实际上是在操作message的单向链表,按message的执行时间进行排序的过程。
三、Handler
1.Field
final MessageQueue mQueue;
final Looper mLooper;
final Callback mCallback;
一个Handler里面包括1个MessageQueue,1个Looper,1个Callback。
可以允许多个Handler对象共用一个Looper对象,也即共用同一个MessageQueue。
2.Method
public void handleMessage(Message msg) {
}
//在这里进行消息的分发
public void dispatchMessage(Message msg) {
if(msg.callback != null) { //
如果Message的Callback不为空的话,会执行其Callback方法
handleCallback(msg); //这个时候,并不会执行Handler的handlerMessage()方法
} else { //
if(mCallback != null) {
//如果Handler的Callback不为空的话,会先执行其Callback
if(mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
所以,Handler在进行消息分发时,会有个先后顺序:1.优先执行Message的Callback,实际上是个Runnable对象;2.如果Message的Callback为空,则优先执行Handler的Callback;3.如果Message、Handler的Callback都为空,最后才会执行handleMessage()方法;4.如果Handler的Callback不为空,并且return true,则不会执行handleMessage()方法,如果return false,则Handler的Callback与handleMessage()均会执行。
可以看到,handleMessage()方法并不一定会执行,它执行的优先级最低。
//实际上是构造了一个Message对象,该Message的Callback为该Runnable
public final boolean post(Runnable r) {
return sendMessageDelayed(getPostMessage(r), 0);
}
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
四、Looper
1.Field
//其实是采用ThreadLocal来存储与每个线程相关的Looper对象
static final ThreadLocal<Looper> sTreadLocal = new TreadLocal<Looper>();
final MessageQueue mQueue; //每个Looper都有一个MessageQueue
final Thread mThread; //与该Looper相关联的线程对象
volatile boolean mRun;
可见,每个Looper对象,都会创建一个MessageQueue对象,并且都会有一个与之相关联的Thread。
2.Method
//创建一个Looper对象,并将Looper对象存储在ThreadLocal当中,在这里建立了Looper对象与Thread之间的关联
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对象
public static Looper myLooper() {
return sThreadLocal.get();
}
//退出Looper循环
public void quit() {
mQueue.quit();
}
//在这里进入消息循环,不停的从消息池里取出消息进行处理。如果消息池里没有消息,则等待,如果有新的消息进来,则被唤醒。
//这里是个死循环,当该Looper对象不需要用到的时候,要确保调用quit()方法,退出消息循环,释放资源。
public static void loop() {
……
…...
for( ; ; ) {
Message msg = queue.next(); //might block
if(msg == null) {
return;
}
……
//这里会调用Handler的dispatchMessage()方法
msg.target.dispatchMessage(msg);
……
//消息处理完毕后,会将该消息对象放入缓存池中
msg.recycle();
}
…...
}