在Android中,通常被使用的消息隊列的代碼在目錄\sources\android-22\android\os下,涉及到以下幾個類文件
Handler.java
Looper.java
Message.javaMessageQueue.java
Message.java
public final class Message implements Parcelable {
public int what; //消息種類
public int arg1; //低開銷的整型參數
public int arg2;
public Object obj; //Object型數據
public Messenger replyTo; //消息處理完後通知給發送者
/*package*/ int flags; //消息標記:正在使用和異步等
/*package*/ long when; //消息創建時的時間
/*package*/ Bundle data; //消息附帶的額外數據
/*package*/ Handler target; //消息接受者,處理者
/*package*/ Runnable callback; //優先使用回調處理來處理消息
/*package*/ Message next; //下一個消息,形成鏈表
private static Message sPool; //消息池中的頭消息
上面中的target,通常由重新實現的Handler子類的handleMessage函數來處理消息
public static Message obtain() { //獲取消息的函數,如果有消息的話則獲取出來m,鏈表指針移動一位,否則則返回一條空消息
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
return new Message();
}
public void sendToTarget() { //發送消息給處理者
target.sendMessage(this); //調用Handler.java中的函數
}
}
MessageQueue.java
public final class MessageQueue {
Message mMessages; //當前要處理的消息
//當需要從鏈表中獲取一個消息時,就會調用next函數,若消息隊列中沒有消息,則會阻塞等待,通過調用nativePollOnce函數來完成
Message next() {...}
boolean enqueueMessage(Message msg, long when) { //按時間順序添加消息
if (msg.target == null) {
throw new IllegalArgumentException("Message must have a target.");
}
if (msg.isInUse()) {
throw new IllegalStateException(msg + " This message is already in use.");
}
synchronized (this) {
if (mQuitting) {
IllegalStateException e = new IllegalStateException(
msg.target + " sending message to a Handler on a dead thread");
Log.w("MessageQueue", e.getMessage(), e);
msg.recycle();
return false;
}
msg.markInUse();
msg.when = when;
Message p = mMessages;
boolean needWake;
if (p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
// Inserted within the middle of the queue. Usually we don't have to wake
// up the event queue unless there is a barrier at the head of the queue
// and the message is the earliest asynchronous message in the queue.
needWake = mBlocked && p.target == null && msg.isAsynchronous();
Message prev;
for (;;) {
prev = p;
p = p.next;
if (p == null || when < p.when) {
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
// We can assume mPtr != 0 because mQuitting is false.
if (needWake) {
nativeWake(mPtr); //調用底層喚醒函數,管道喚醒
}
}
return true;
}