从源码角度简单分析下Handler发消息流程
程序员文章站
2022-06-03 23:39:10
一、发送消息(sendMssage)handler.sendMessage(message)handler.sendMessageDelayed()等发送消息的方法,最终都会走到sendMessageAtTime public boolean sendMessageAtTime(Message msg, long uptimeMillis) { MessageQueue queue = mQueue; if (queue == null) { R...
一、发送消息(sendMssage)
handler.sendMessage(message)
handler.sendMessageDelayed()等发送消息的方法,最终都会走到sendMessageAtTime
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);
}
二、将Mssage存入队列
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;//这里记录下msg.target就是Handler自己
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
在sendMessageAtTime中将msg放到了队列,这个队列是链表形式的队列,而且需要以时间排序
三,从MessageQueue中取出Message
然后我们再看看MessageQueue的next方法
Message next() {
...
for (;;) {
...
synchronized (this) {
// Try to retrieve the next message. Return if found.
final long now = SystemClock.uptimeMillis();
Message prevMsg = null;
Message msg = mMessages;
if (msg != null && msg.target == null) {
// Stalled by a barrier. Find the next asynchronous message in the queue.
do {
prevMsg = msg;
msg = msg.next;//这里先在do while中取消息
} while (msg != null && !msg.isAsynchronous());
}
if (msg != null) {
if (now < msg.when) {//然后用当前时间对比,看发送时间有没有到
// Next message is not ready. Set a timeout to wake up when it is ready.
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
} else {
// Got a message.
mBlocked = false;
if (prevMsg != null) {
prevMsg.next = msg.next;
} else {
mMessages = msg.next;
}
msg.next = null;
if (DEBUG) Log.v(TAG, "Returning message: " + msg);
msg.markInUse();
return msg;//如果到了发送时间,直接返回消息
}
} else {
// No more messages.
nextPollTimeoutMillis = -1;
}
.....
}
}
1.这里先在do while中取消息
2.然后用当前时间对比,看发送时间有没有到
3.如果到了发送时间,直接返回消息
然后看看下Looper的loop()方法,
public static void loop() {
final Looper me = myLooper();
...
final MessageQueue queue = me.mQueue;
...
for (;;) {//这里有个死循环,从MessageQueue 中取Message
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
...
final long dispatchStart = needStartTime ? SystemClock.uptimeMillis() : 0;
final long dispatchEnd;
try {
msg.target.dispatchMessage(msg);//然后进行消息分发
dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
...
msg.recycleUnchecked();
}
}
loop()里面主要做了两件事
1.在一个死循环里面,从从MessageQueue 中取Message
2.调用msg.target.dispatchMessage(msg)将Message分发出去
四,将取出Message的进行分发
在上面Handler的enqueueMessage源码里面可以看出这个target就是Handler,所以我们再跟一下Handler的dispatchMessage方法
public void dispatchMessage(Message msg) {
if (msg.callback != null) {//这里的callback就是用Handler的post方法发送的Runnable 对象,待会看源码
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);//在这里调用Handler的handleMessage方法
}
这里补下Handler的post相关源码
public final boolean post(Runnable r){
return sendMessageDelayed(getPostMessage(r), 0);
}
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;//在这里给callback 赋值
return m;
}
public final boolean sendMessageDelayed(Message msg, long delayMillis){
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);//这里还是通过sendMessageAtTime将消息发送给了队列
}
本文地址:https://blog.csdn.net/zzq2006/article/details/109632748