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

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

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

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

当前名称:Android应用程序消息处理机制(Looper、Handler)分析(6)
标题链接:http://www.mswzjz.cn/qtweb/news22/330572.html

攀枝花网站建设、攀枝花网站运维推广公司-贝锐智能,是专注品牌与效果的网络营销公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 贝锐智能