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

调用以下函数的时候,有可能会让线程进入等待状态。

什么情况下,线程会进入等待状态呢?

两种情况,一是当消息队列中没有消息时,它会使线程进入等待状态;;二是消息队列中有消息,但是消息指定了执行的时间,而现在还没有到这个时间,线程也会进入等待状态。

消息队列中的消息是按时间先后来排序的,后面我们在分 析消息的发送时会看到。

这个函数最关键的地方便是从消息队列中获取下一个要处理的消息了,即MessageQueue.next函数,它实现frameworks/base/core/java/Android/os/MessageQueue.java文件中:

 
 
  1. [java] view plaincopypublic class MessageQueue { 
  2. ...... 
  3. final Message next() { 
  4. int pendingIdlehandlerCount = -1// -1 only during first iteration 
  5. int nextPollTimeoutMillis = 0
  6. for (;;) { 
  7. if (nextPollTimeoutMillis != 0) { 
  8. Binder.flushPendingCommands(); 
  9. nativePollOnce(mPtr, nextPollTimeoutMillis); 
  10. synchronized (this) { 
  11. // Try to retrieve the next message. Return if found. 
  12. final long now = SystemClock.uptimeMillis(); 
  13. final Message msg = mMessages; 
  14. if (msg != null) { 
  15. final long when = msg.when; 
  16. if (now >= when) { 
  17. mBlocked = false
  18. mMessages = msg.next; 
  19. msg.next = null
  20. if (Config.LOGV) Log.v("MessageQueue""Returning message: " + msg); 
  21. return msg; 
  22. else { 
  23. nextPollTimeoutMillis = (int) Math.min(when - now, Integer.MAX_VALUE); 
  24. else { 
  25. nextPollTimeoutMillis = -1
  26. // If first time, then get the number of idlers to run. 
  27. if (pendingIdleHandlerCount < 0) { 
  28. pendingIdleHandlerCount = mIdleHandlers.size(); 
  29. if (pendingIdleHandlerCount == 0) { 
  30. // No idle handlers to run. Loop and wait some more. 
  31. mBlocked = true
  32. continue
  33. if (mPendingIdleHandlers == null) { 
  34. mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 
  35. ]; 
  36. mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers); 
  37. // Run the idle handlers. 
  38. // We only ever reach this code block during the first iteration. 
  39. for (int i = 0; i < pendingIdleHandlerCount; i++) { 
  40. final IdleHandler idler = mPendingIdleHandlers[i]; 
  41. mPendingIdleHandlers[i] = null// release the reference to the handler 
  42. boolean keep = false
  43. try { 
  44. keep = idler.queueIdle(); 
  45. catch (Throwable t) { 
  46. Log.wtf("MessageQueue""IdleHandler threw exception", t); 
  47. if (!keep) { 
  48. synchronized (this) { 
  49. mIdleHandlers.remove(idler); 
  50. // Reset the idle handler count to 0 so we do not run them again. 
  51. pendingIdleHandlerCount = 0
  52. // While calling an idle handler, a new message could have been 
  53. livered 
  54. // so go back and look again for a pending message without waiting. 
  55. nextPollTimeoutMillis = 0
  56. ...... 
  57. }

执行下面语句是看看当前消息队列中有没有消息:

 
 
  1. [java] view plaincopynativePollOnce(mPtr, nextPollTimeoutMillis); 

这是一个JNI方法,我们等一下再分析,这里传入的参数mPtr就是指向前面我们在JNI层创建的NativeMessageQueue对象了,而参数 nextPollTimeoutMillis则表示如果当前消息队列中没有消息,它要等待的时候,for循环开始时,传入的值为0,表示不等待。

THE END