Android应用程序消息处理机制(Looper、Handler)分析(7)

移动开发 Android
这里说的等待,是空闲等待,而不是忙等待,因此,在进入空闲等待状态前,如果应用程序注册了IdleHandler接口来处理一些事情,那么就会先执 行这里IdleHandler,然后再进入等待状态。

如果消息队列中有消息,并且当前时候大于等于消息中的执行时间,那么就直接返回这个消息给Looper.loop消息处理,否则的话就要等待到消息的执行时间:

[java] view plaincopynextPollTimeoutMillis = (int) Math.min(when - now, Integer.MAX_VALUE);

如果消息队列中没有消息,那就要进入无穷等待状态直到有新消息了:

[java] view plaincopynextPollTimeoutMillis = -1;

-1表示下次调用nativePollOnce时,如果消息中没有消息,就进入无限等待状态中去。

当前nativePollOnce返回后,就去看看消息队列中有没有消息:

  1. [java] view plaincopyfinal Message msg = mMessages; 
  2. if (msg != null) { 
  3. final long when = msg.when; 
  4. if (now >= when) { 
  5. mBlocked = false
  6. mMessages = msg.next; 
  7. msg.next = null
  8. if (Config.LOGV) Log.v("MessageQueue""Returning message: " + msg); 
  9. return msg; 
  10. else { 
  11. nextPollTimeoutMillis = (int) Math.min(when - now, Integer.MAX_VALUE); 
  12. else { 
  13. nextPollTimeoutMillis = -1
  14. }

这里计算出来的等待时间都是在下次调用nativePollOnce时使用的。

这里说的等待,是空闲等待,而不是忙等待,因此,在进入空闲等待状态前,如果应用程序注册了IdleHandler接口来处理一些事情,那么就会先执 行这里IdleHandler,然后再进入等待状态。IdlerHandler是定义在MessageQueue的一个内部类:

  1. [java] view plaincopypublic class MessageQueue { 
  2. ...... 
  3. /** 
  4. * Callback interface for discovering when a thread is going to block 
  5. * waiting for more messages. 
  6. */ 
  7. public static interface IdleHandler { 
  8. /** 
  9. * Called when the message queue has run out of messages and will now 
  10. * wait for more. Return true to keep your idle handler active, false 
  11. * to have it removed. This may be called if there are still messages 
  12. * pending in the queue, but they are all scheduled to be dispatched 
  13. * after the current time. 
  14. */ 
  15. boolean queueIdle(); 
  16. ...... 

它只有一个成员函数queueIdle,执行这个函数时,如果返回值为false,那么就会从应用程序中移除这个IdleHandler,否则的话就会在 应用程序中继续维护着这个IdleHandler,下次空闲时仍会再执会这个IdleHandler。MessageQueue提供了 addIdleHandler和removeIdleHandler两注册和删除IdleHandler。

回到MessageQueue函数中,它接下来就是在进入等待状态前,看看有没有IdleHandler是需要执行的:

  1.   [java] view plaincopy// If first time, then get the number of idlers to 
  2. run. 
  3.   if (pendingIdleHandlerCount < 0) { 
  4.   pendingIdleHandlerCount = mIdleHandlers.size(); 
  5.   } 
  6.   if (pendingIdleHandlerCount == 0) { 
  7.   // No idle handlers to run. Loop and wait some more. 
  8.   mBlocked = true
  9.   continue
  10.   } 
  11.   if (mPendingIdleHandlers == null) { 
  12.   mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 
  13. 4)]; 
  14.   } 
  15.   mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers); 

如果没有,即pendingIdleHandlerCount等于0,那下面的逻辑就不执行了,通过continue语句直接进入下一次循环,否则就要把 注册在mIdleHandlers中的IdleHandler取出来,放在mPendingIdleHandlers数组中去。

接下来就是执行这些注册了的IdleHanlder了:

  1. [java] view plaincopy// Run the idle handlers. 
  2. // We only ever reach this code block during the first iteration. 
  3. for (int i = 0; i < pendingIdleHandlerCount; i++) { 
  4. final IdleHandler idler = mPendingIdleHandlers[i]; 
  5. mPendingIdleHandlers[i] = null// release the reference to the handler 
  6. boolean keep = false
  7. try { 
  8. keep = idler.queueIdle(); 
  9. catch (Throwable t) { 
  10. Log.wtf("MessageQueue""IdleHandler threw exception", t); 

 

责任编辑:闫佳明 来源: bbs.9ria
相关推荐

2014-05-22 14:57:28

Android消息处理机制Looper

2014-05-22 15:15:53

Android消息处理机制Looper

2014-05-22 15:18:25

Android消息处理机制Looper

2014-05-22 15:45:58

Android消息处理机制Looper

2014-05-22 15:07:44

Android消息处理机制Looper

2014-05-22 15:48:50

Android消息处理机制Looper

2014-05-22 15:00:16

Android消息处理机制Looper

2014-05-22 15:41:59

Android消息处理机制Looper

2014-05-22 15:38:27

Android消息处理机制Looper

2014-05-22 15:04:00

Android消息处理机制Looper

2011-04-28 11:01:40

Android消息处理LooperHandler

2011-11-23 09:33:45

HandlerLooperMessage

2014-05-27 10:13:57

移动技术半月刊

2016-10-21 13:03:18

androidhandlerlooper

2011-09-05 17:40:40

MTK定时器

2011-03-17 09:20:05

异常处理机制

2021-08-12 16:28:10

AndroidHandleLooper

2014-05-27 14:59:24

AndroidActivitysingleTask

2023-03-08 08:54:59

SpringMVCJava

2023-06-15 14:09:00

解析器Servlet容器
点赞
收藏

51CTO技术栈公众号