
大家使用Handler的时候,一般都是在子线程中处理耗时逻辑,并发送Message。在主线程中处理消息,并进行UI *** 作,在这一连串行云流水的 *** 作中,Handler到底是怎样执行的呢?看看源码就能发现其中的奥秘。
首先说明下Handler的 *** 作流程:
Handler发送消息sendMessage(msg)—>MessageQueue接收消息,并秉持先进先出的原则—>Looper从消息队列中获取消息,并将Message分配给对应的Handler,即执行回调handleMessage()方法处理消息
源码探究:
- 先看消息的发送,以sendMessage()为例,源码可自行查看,本人使用的是Android 12版本。
public final boolean sendMessage(@NonNull Message msg) {
return sendMessageDelayed(msg, 0);
}
- sendMessage()实际上是调用sendMessageDelayed(msg, 0)
public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
- sendMessageDelayed()方法调用的是sendMessageAtTime()方法
public boolean sendMessageAtTime(@NonNull 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);
}
- sendMessageAtTime()方法调用的是enqueueMessage()方法,注意这是Handler里面的方法!
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,long uptimeMillis) {
msg.target = this;
msg.workSourceUid = ThreadLocalWorkSource.getUid();
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
- enqueueMessage()方法调用的是MessageQueue中的enqueueMessage()方法,可以理解为Message入队,进入消息队列排队。
@UnsupportedAppUsage
Message next() {
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;
}
}
- 既然有入队的方法,当然会有出队的方法。调用MessageQueue的next()方法取出消息,这时就需要Looper对象来取消息了。
public static void loop() {
//部分代码省略,只写重点代码,源码可自行查看
for (;;) {
if (!loopOnce(me, ident, thresholdOverride)) {
return;
}
}
}
private static boolean loopOnce(final Looper me,final long ident, final int thresholdOverride) {
//部分代码省略,只写重点代码
Message msg = me.mQueue.next(); // might block
//省略中间代码
try {
msg.target.dispatchMessage(msg);
if (observer != null) {
observer.messageDispatched(token, msg);
}
}
- Looper对象会调用loop()方法来获取Message,如上源码中是先调用loop()方法,再调用loopOnce()方法拿到Message对象,从而Looper对象就拿到Message了。拿到Message后,会执行Message中target对象的dispatchMessage()方法,实际上target就是Handler对象,源码中可以看到。
public void dispatchMessage(@NonNull Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
- 上面的代码可以看到dispatchMessage()方法中调用了handleMessage()方法,这样一条Message从Handler发送,到进入队列,最后处理消息的完整流程就结束了。
本人初学Android,若有不确之处,请不吝赐教,谢谢!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)