Android應(yīng)用程序消息處理機(jī)制(Looper、Handler)分析(6)
調(diào)用以下函數(shù)的時(shí)候,有可能會(huì)讓線程進(jìn)入等待狀態(tài)。
什么情況下,線程會(huì)進(jìn)入等待狀態(tài)呢?
兩種情況,一是當(dāng)消息隊(duì)列中沒有消息時(shí),它會(huì)使線程進(jìn)入等待狀態(tài);;二是消息隊(duì)列中有消息,但是消息指定了執(zhí)行的時(shí)間,而現(xiàn)在還沒有到這個(gè)時(shí)間,線程也會(huì)進(jìn)入等待狀態(tài)。
消息隊(duì)列中的消息是按時(shí)間先后來排序的,后面我們在分 析消息的發(fā)送時(shí)會(huì)看到。
這個(gè)函數(shù)最關(guān)鍵的地方便是從消息隊(duì)列中獲取下一個(gè)要處理的消息了,即MessageQueue.next函數(shù),它實(shí)現(xiàn)frameworks/base/core/java/android/os/MessageQueue.java文件中:
- [java] view plaincopypublic class MessageQueue {
- ......
- final Message next() {
- int pendingIdleHandlerCount = -1; // -1 only during first iteration
- int nextPollTimeoutMillis = 0;
- for (;;) {
- if (nextPollTimeoutMillis != 0) {
- Binder.flushPendingCommands();
- }
- nativePollOnce(mPtr, nextPollTimeoutMillis);
- synchronized (this) {
- // Try to retrieve the next message. Return if found.
- final long now = SystemClock.uptimeMillis();
- final Message msg = mMessages;
- if (msg != null) {
- final long when = msg.when;
- if (now >= when) {
- mBlocked = false;
- mMessages = msg.next;
- msg.next = null;
- if (Config.LOGV) Log.v("MessageQueue", "Returning message: " + msg);
- return msg;
- } else {
- nextPollTimeoutMillis = (int) Math.min(when - now, Integer.MAX_VALUE);
- }
- } else {
- nextPollTimeoutMillis = -1;
- }
- // If first time, then get the number of idlers to run.
- if (pendingIdleHandlerCount < 0) {
- 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,
- ];
- }
- 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
- livered
- // so go back and look again for a pending message without waiting.
- nextPollTimeoutMillis = 0;
- }
- }
- ......
- }
執(zhí)行下面語句是看看當(dāng)前消息隊(duì)列中有沒有消息:
- [java] view plaincopynativePollOnce(mPtr, nextPollTimeoutMillis);
這是一個(gè)JNI方法,我們等一下再分析,這里傳入的參數(shù)mPtr就是指向前面我們在JNI層創(chuàng)建的NativeMessageQueue對象了,而參數(shù) nextPollTimeoutMillis則表示如果當(dāng)前消息隊(duì)列中沒有消息,它要等待的時(shí)候,for循環(huán)開始時(shí),傳入的值為0,表示不等待。