0
点赞
收藏
分享

微信扫一扫

Android 消息机制之 Handler 发送消息的深入源码分析 [ 七 ]

Android 消息机制深入源码分析 [ 一 ]
Android 消息机制之 ThreadLocal 深入源码分析 [ 二 ]
Android 消息机制之 Looper 深入源码分析 [ 三 ]
Android 消息机制之 Message 与消息对象池的深入源码分析 [ 四 ]
Android 消息机制之 MessageQueue 深入源码分析 [ 五 ]
Android 消息机制之初识Handler [ 六 ]
Android 消息机制之 Handler 发送消息的深入源码分析 [ 七 ]
Android 消息机制之 MessageQueue.next() 消息取出的深入源码分析 [ 八 ]
Android 消息机制之消息的其他处理深入源码分析 [ 九 ]
Android 消息机制总结 [ 十 ]

上一章, 初步认识了 Handler, 本章节将继续接着上一章开始对消息的具体发送进行学习和分析.

1. Handler 消息发送的分类

  • Handler 平时发送消息主要是调用两大类方法, 分别是 send 方案 以及 post 方案

  • send 方案

    • boolean sendMessage(Message msg)
    • boolean sendEmptyMessage(int what)
    • boolean sendEmptyMessageDelayed(int what, long delayMillis)
    • boolean sendEmptyMessageAtTime(int what, long uptimeMillis)
    • boolean sendMessageDelayed(Message msg, long delayMillis)
    • boolean sendMessageAtTime(Message msg, long uptimeMillis)
    • boolean sendMessageAtFrontOfQueue(Message msg)
  • post 方案

    • boolean post(Runnable r)
    • boolean postAtFrontOfQueue(Runnable r)
    • boolean postAtTime(Runnable r, long uptimeMillis)
    • boolean postAtTime(Runnable r, Object token, long uptimeMillis)
    • boolean postDelayed(Runnable r, long delayMillis)
    • boolean postDelayed(Runnable r, Object token, long delayMillis)
       

 

2. send 方案.

还是先从 send 方案的第一个开始看, 也就是我们最常用的一个.

2.1 boolean sendMessage(Message msg)
Handler.java 602 行.

public final boolean sendMessage(Message msg){
    return sendMessageDelayed(msg, 0);
}
  • 官方注释:
  • 分析

 
2.2 boolean sendMessageDelayed(Message msg, long delayMillis)
Handler.java 662 行.

public final boolean sendMessageDelayed(Message msg, long delayMillis){
    //判断 delayMillis 是否小于0
    if (delayMillis < 0) {
        delayMillis = 0;
    }
    return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
  • 分析

 
2.3 boolean sendMessageAtTime(Message msg, long uptimeMillis)
Handler.java 689 行.

public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
    MessageQueue queue = mQueue;
    if (queue == null) {
        RuntimeException e = new RuntimeException(this + " sendMessageAtTime() called with no mQueue");
        Log.w("Looper", e.getMessage(), e);
        return false;
    }
    return enqueueMessage(queue, msg, uptimeMillis);
}
  • 官方注释
  • 分析

 
2.4 boolean enqueueMessagee(MessageQueue queue, Message msg, long uptimeMillis)
Handler.java 740 行.

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
    msg.target = this;
    if (mAsynchronous) {
        msg.setAsynchronous(true);
    }
    return queue.enqueueMessage(msg, uptimeMillis);
}
  • 分析

 
2.5 MessageQueue boolean enqueueMessage(Message msg, long when)
MessageQueue.java 536 行, 由于代码过长, 将会分为多段来分析.

boolean enqueueMessage(Message msg, long when) {
  //第一步
  if (msg.target == null) {
      throw new IllegalArgumentException("Message must have a target.");
  }
  //第二步
  if (msg.isInUse()) {
      throw new IllegalStateException(msg + " This message is already in use.");
  }
  • 分析
  //第三步
  synchronized (this) {
      //第四步
      if (mQuitting) {
          IllegalStateException e = new IllegalStateException(msg.target + " sending message to a Handler on a dead thread");
          Log.w(TAG, e.getMessage(), e);
          msg.recycle();
          return false;
      }
      //第五步
      msg.markInUse();
      msg.when = when;
      Message p = mMessages;
      boolean needWake;
      //第六步
      if (p == null || when == 0 || when < p.when) {
          //把 msg 的下一个元素设置为 p
          msg.next = p;
          //把 msg 设置为链表的头部元素
          mMessages = msg;
          //如果有阻塞,则需要唤醒
          needWake = mBlocked;
      } 
  • 分析
      //第七步
      else {
          //第八步
          needWake = mBlocked && p.target == null && msg.isAsynchronous();
          Message prev;
          //第九步
          //不断遍历消息队列, 根据 when 的比较找到合适的插入 message 的位置
          for (;;) {
              prev = p;
              p = p.next;
              //第十步
              if (p == null || when < p.when) {
                  break;
              }
              //第十一步
              if (needWake && p.isAsynchronous()) {
                  needWake = false;
              }
          }
          //第十二步
          msg.next = p; // invariant: p == prev.next
          prev.next = msg;
      }
            //第十三步
      if (needWake) {
          nativeWake(mPtr);
      }
  }
  //第十四步
  return true;
}
  • 分析

 
以上就是我们常用的 sendMessage(Message msg) 消息发送流程, 接下来看 send 方案中剩下的.

2.5 boolean sendMessageAtFrontOfQueue(Message msg)
Handler.java 712 行.

public final boolean sendMessageAtFrontOfQueue(Message msg) {
    MessageQueue queue = mQueue;
    if (queue == null) {
        RuntimeException e = new RuntimeException(this + " sendMessageAtTime() called with no mQueue");
        Log.w("Looper", e.getMessage(), e);
        return false;
    }
    return enqueueMessage(queue, msg, 0);
}
  • 官方翻译
  • 解析

 
剩下的 boolean sendEmptyMessage(int what)boolean sendEmptyMessageDelayed(int what, long uptimeMillis) 就不再分析了, 非常简单, 可以自己看一下.
 
send 方案的最后, 都是会调用 enqueueMessage() 入队方法来完成消息的入队.

3. post 方案

3.1 boolean post(Runnable r)
Handler.java 393行.

public final boolean post(Runnable r){
   return  sendMessageDelayed(getPostMessage(r), 0);
}
  • 官方注释

-分析

看一下调用的 getPostMessage(Runnable r)

 
3.1 Message getPostMessage(Runnable r)
Handler.java 859 行

private static Message getPostMessage(Runnable r) {
    Message m = Message.obtain();
    m.callback = r;
    return m;
}
  • 分析

由此我们可以得知 boolean post(Runnable r) 方法的内部也是通过 Message.obtain 来获取一个 Message 对象. 然后仅仅只是把 Message 对象的 Runnable callback 赋值而已. 最后还是调用了 send 方案的某个流程最终调用到入队方法.

后面剩余的 post 方法依旧如此, 只是调用的是不同的 send 方案中的方法.

 

4.消息发送总结

Handler 发送消息 (除障栅外), 无论是 send 还是 post 最终都会调用 MessageQueue.enqueueMessage(Message msg, long when) 方法进行入队. 下图展示了他们之间的关系.

消息发送出去了, 剩下的就是取出消息以及其他处理了, 将在下一章分析.

举报

相关推荐

Android Handler 消息机制

0 条评论