官方注釋:
MessageQueue是保存消息列表的低級(jí)別類,消息由Looper對(duì)象派發(fā)俺亮。消息并不是直接添加到MessageQueue中的,而是通過(guò)與Looper對(duì)象關(guān)聯(lián)的MessageQueue.IdleHandler對(duì)象添加十偶。
調(diào)用Looper.myQueue方法可以獲取當(dāng)前線MessageQueue转捕。
參數(shù)解釋:
private int mPtr; // 使用本機(jī)code
表示MessageQueue是否允許退出
mQuitAllowed
存放IdleHandler對(duì)象的一個(gè)ArrayList
private final ArrayList<IdleHandler> mIdleHandlers = new
ArrayList<IdleHandler>();
一個(gè)IdleHandler數(shù)組
private IdleHandler[] mPendingIdleHandlers;
判斷Thread是否退出
private boolean mQuitting;
是否被阻塞
private boolean mBlocked;
下一個(gè)障礙記號(hào)?耗式?胁住?
private int mNextBarrierToken;
jni調(diào)底層的c
private native static long nativeInit();
private native static void nativeDestroy(long ptr);
private native static void nativePollOnce(long ptr, int timeoutMillis);
private native static void nativeWake(long ptr);
private native static boolean nativeIsIdling(long ptr);
IdleHandler在Handler空閑時(shí)執(zhí)行,好處在于可以不用指定一個(gè)將來(lái)時(shí)間刊咳,只要線程空閑了彪见,就可以執(zhí)行它指定的操作。比較適合那種需要在將來(lái)執(zhí)行操作娱挨,但是又不知道需要指定多少延遲時(shí)間的操作
public static interface IdleHandler {
boolean queueIdle();
}
添加和刪除IdleHandler的方法
addIdleHandler(IdleHandler handler)
removeIdleHandler(IdleHandler handler)
創(chuàng)建消息隊(duì)列
MessageQueue(boolean quitAllowed) {
mQuitAllowed = quitAllowed;
mPtr = nativeInit();//通過(guò)native方法初始化消息隊(duì)列
}
對(duì)象銷毀時(shí)余指,該方法finalize()被自動(dòng)調(diào)用。主要是通過(guò)native方法銷毀前創(chuàng)建的nativeMessageQueue方法
protected void finalize() throws Throwable {
try {
dispose();
} finally {
super.finalize();
}
}
private void dispose() {
if (mPtr != 0) {
nativeDestroy(mPtr);
mPtr = 0;
}
}
//next方法會(huì)取出下一個(gè)Message(從頭部弱伟印)酵镜,如果沒(méi)有Message可以處理,就可以處理下IdleHandler
Message next() {
// Return here if the message loop has already quit and been disposed.
// This can happen if the application tries to restart a looper after quit
// which is not supported.
final long ptr = mPtr;
if (ptr == 0) {
return null;
}
int pendingIdleHandlerCount = -1; // -1 only during first iteration
int nextPollTimeoutMillis = 0;
for (;;) {
if (nextPollTimeoutMillis != 0) {
//等待刷新
Binder.flushPendingCommands();
}
//調(diào)用native層進(jìn)行消息標(biāo)示 0立即返回 -1 等待
//一:是當(dāng)消息隊(duì)列中沒(méi)有消息時(shí)線程進(jìn)入等待柴钻,二:消息指定了時(shí)間淮韭,而現(xiàn)在還沒(méi)有到這個(gè)時(shí)間
nativePollOnce(ptr, nextPollTimeoutMillis);
synchronized (this) {
// 試圖獲取下一條消息。如果發(fā)現(xiàn)返回贴届。
final long now = SystemClock.uptimeMillis();
Message prevMsg = null;
Message msg = mMessages;
//尋找下一個(gè)異步消息隊(duì)列中
if (msg != null && msg.target == null) {
do {
prevMsg = msg;
msg = msg.next;
//(flags & FLAG_ASYNCHRONOUS) != 0; //FLAG_ASYNCHRONOUS = 1 << 1;
} while (msg != null && !msg.isAsynchronous());
}
if (msg != null) {
if (now < msg.when) {
// 下一個(gè)消息沒(méi)有準(zhǔn)備好靠粪。設(shè)置一個(gè)超時(shí)時(shí)間作為下次休眠的依據(jù)
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
} else {
// Got a message.
mBlocked = false;
if (prevMsg != null) {
prevMsg.next = msg.next;
} else {
mMessages = msg.next;
}
msg.next = null;
if (false) Log.v("MessageQueue", "Returning message: " + msg);
return msg;
}
} else {
// 沒(méi)有更多信息
nextPollTimeoutMillis = -1;
}
// 如果還有消息沒(méi)處理,交給底層處理
if (mQuitting) {
dispose();
return null;
}
//?????
if (pendingIdleHandlerCount < 0
&& (mMessages == null || now < mMessages.when)) {
pendingIdleHandlerCount = mIdleHandlers.size();
}
if (pendingIdleHandlerCount <= 0) {
// No idle handlers to run. Loop and wait some more.
mBlocked = true;//阻塞
continue;
}
if (mPendingIdleHandlers == null) {
mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
}
mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
}
// Run the idle handlers.
// We only ever reach this code block during the first iteration.
for (int i = 0; i < pendingIdleHandlerCount; i++) {
final IdleHandler idler = mPendingIdleHandlers[i];
mPendingIdleHandlers[i] = null; // release the reference to the handler
boolean keep = false;
try {
//消息處理完畢后毫蚓,是否還保持活躍
keep = idler.queueIdle();
} catch (Throwable t) {
Log.wtf("MessageQueue", "IdleHandler threw exception", t);
}
if (!keep) {
synchronized (this) {
mIdleHandlers.remove(idler);
}
}
}
// Reset the idle handler count to 0 so we do not run them again.
pendingIdleHandlerCount = 0;
// While calling an idle handler, a new message could have been delivered
// so go back and look again for a pending message without waiting.
nextPollTimeoutMillis = 0;
}
}
總結(jié):
每個(gè)Message之間是串連在一起的占键,Message只要知道自己的前面一個(gè)Message和后面一個(gè)Message就可以了,Message之間的排序通過(guò)用時(shí)間戳來(lái)排序,時(shí)間戳小的排在前面绍些。
再配合上handler對(duì)于消息的取出捞慌,第一個(gè)Message的時(shí)間到了耀鸦,就取隊(duì)列的第一個(gè)Message柬批,取完之后啸澡,將第一個(gè)Message置空,這樣第二個(gè)Message就排在第一個(gè)了氮帐,依此類推嗅虏。
遺留問(wèn)題:
1.pendingIdleHandlerCount < 0 完后為什么還有一個(gè)
pendingIdleHandlerCount <= 0 的判斷,為什么這樣寫(xiě)上沐?
2.if (false) Log.v 這個(gè)false的寫(xiě)法奇怪皮服?
3.為什么一定要用jni來(lái)處理?