加入收藏 | 设为首页 | 会员中心 | 我要投稿 东莞站长网 (https://www.0769zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长资讯 > 评论 > 正文

Android消息机制Handler,有必要再讲一次

发布时间:2019-07-28 07:42:38 所属栏目:评论 来源:Engineers
导读:副标题#e# 我们在日常开发中,总是不可避免的会用到 Handler,虽说 Handler 机制并不等同于 Android 的消息机制,但 Handler 的消息机制在 Android 开发中早已谙熟于心,非常重要! 通过本文,你可以非常容易得到一下问题的答案: Handler、Looper、Message

顾名思义,MessageQueue 就是消息队列,即存放多条消息 Message 的容器,它采用的是单向链表数据结构,而非队列。它的 next() 指向链表的下一个 Message 元素。

  1. boolean enqueueMessage(Message msg, long when) { 
  2.  // ... 省略一些检查代码 
  3.  synchronized (this) { 
  4.  // ... 省略一些检查代码 
  5.  msg.markInUse(); 
  6.  msg.when = when; 
  7.  Message p = mMessages; 
  8.  boolean needWake; 
  9.  if (p == null || when == 0 || when < p.when) { 
  10.  // New head, wake up the event queue if blocked. 
  11.  msg.next = p; 
  12.  mMessages = msg; 
  13.  needWake = mBlocked; 
  14.  } else { 
  15.  // Inserted within the middle of the queue. Usually we don't have to wake 
  16.  // up the event queue unless there is a barrier at the head of the queue 
  17.  // and the message is the earliest asynchronous message in the queue. 
  18.  needWake = mBlocked && p.target == null && msg.isAsynchronous(); 
  19.  Message prev; 
  20.  for (;;) { 
  21.  prev = p; 
  22.  p = p.next; 
  23.  if (p == null || when < p.when) { 
  24.  break; 
  25.  } 
  26.  if (needWake && p.isAsynchronous()) { 
  27.  needWake = false; 
  28.  } 
  29.  } 
  30.  msg.next = p; // invariant: p == prev.next 
  31.  prev.next = msg; 
  32.  } 
  33.  // We can assume mPtr != 0 because mQuitting is false. 
  34.  if (needWake) { 
  35.  nativeWake(mPtr); 
  36.  } 
  37.  } 
  38.  return true; 

从入队消息 enqueueMessage() 的实现来看,它的主要操作其实就是单链表的插入操作,这里就不做过多的解释了,我们可能应该更多的关心它的出队操作方法 next():

  1. Message next() { 
  2.  // ... 
  3.  int nextPollTimeoutMillis = 0; 
  4.  for (;;) { 
  5.  // ... 
  6.  nativePollOnce(ptr, nextPollTimeoutMillis); 
  7.  synchronized (this) { 
  8.  // Try to retrieve the next message. Return if found. 
  9.  final long now = SystemClock.uptimeMillis(); 
  10.  Message prevMsg = null; 
  11.  Message msg = mMessages; 
  12.  if (msg != null && msg.target == null) { 
  13.  // Stalled by a barrier. Find the next asynchronous message in the queue. 
  14.  do { 
  15.  prevMsg = msg; 
  16.  msg = msg.next; 
  17.  } while (msg != null && !msg.isAsynchronous()); 
  18.  } 
  19.  if (msg != null) { 
  20.  if (now < msg.when) { 
  21.  // Next message is not ready. Set a timeout to wake up when it is ready. 
  22.  nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE); 
  23.  } else { 
  24.  // Got a message. 
  25.  mBlocked = false; 
  26.  if (prevMsg != null) { 
  27.  prevMsg.next = msg.next; 
  28.  } else { 
  29.  mMessages = msg.next; 
  30.  } 
  31.  msg.next = null; 
  32.  if (DEBUG) Log.v(TAG, "Returning message: " + msg); 
  33.  msg.markInUse(); 
  34.  return msg; 
  35.  } 
  36.  } else { 
  37.  // No more messages. 
  38.  nextPollTimeoutMillis = -1; 
  39.  } 
  40.  //... 
  41.  } 
  42.  //... 
  43.  // While calling an idle handler, a new message could have been delivered 
  44.  // so go back and look again for a pending message without waiting. 
  45.  nextPollTimeoutMillis = 0; 
  46.  } 

(编辑:东莞站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读