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)
方法进行入队. 下图展示了他们之间的关系.
消息发送出去了, 剩下的就是取出消息以及其他处理了, 将在下一章分析.