今天做项目看到这段代码时产生了一些疑惑,又打开 Handler 源码看了看相关的逻辑。简短的几行代码背后却有着复杂的逻辑。真是越看越爽啊!!!
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// do something
}
},2000);
handler 的 postDelayed()方法的流程:
1.执行 postDelayed 方法
public final boolean postDelayed(Runnable r, long delayMillis)
{
return sendMessageDelayed(getPostMessage(r), delayMillis);
}
2.通过 getPostMessage 方法把 runnable 对象封装成为 message 对象中的 callback 属性
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
3.执行 sendMessageDelayed 方法
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
4.执行 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);
}
5.最后通过 enqueueMessage 方法把 msg 添加到 enqueueMessage 中,并把发送消息的 handler 对象赋值到 msg.target 属性中
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this; // 把发送消息的 handler对象赋值到 msg.target 属性中
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
6.在 Looper 中循环取出 queue 中的 msg,执行 msg.target.dispatchMessage(msg); 调用 handler 中的 dispatchMessage(msg); 方法分发消息
public static void loop() {
final Looper me = myLooper(); // 返回当前 looper
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue;
// Make sure the identity of this thread is that of the local process,
// and keep track of what that identity token actually is.
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
for (;;) { // 循环取出queue 中的msg
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
// This must be in a local variable, in case a UI event sets the logger
。。。
final long end;
try {
msg.target.dispatchMessage(msg); // 使用发送消息的 handler 分发消息
end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
。。。。
msg.recycleUnchecked();
}
}
7.执行 handler 的 dispatchMessage 方法,判断 msg 的类型,此时的 msg.callback 不为 null ,执行 handleCallback(msg)
/*
* 根据 msg 的不同类型分发消息
*/
public void dispatchMessage(Message msg) {
if (msg.callback != null) {//
handleCallback(msg);// 这时执行这里,在handler.post(runnable)或 postDelayed(runnable,1000)的时候
} else {
if (mCallback != null) { // mCallback :是在创建 handler 的时候,通过构造方法里的参数 Callback 传入的,也就是 new Handler(callback);
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg); // 通过无参的构造函数创建,也就是 new Handler();
}
}
8.在 handleCallback 中执行 run 方法
private static void handleCallback(Message message) {
message.callback.run();
}
9.也就是 postDelayed 方法中的 runnable 中的 run , 完成整个消息的发送与处理
/* * The runnable will be run on the thread to which this handler
* is attached.
*/
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// 这里仍然是在ui线程中执行(因为handler 是在ui线程中)
}
},2000);
这已经是第三次看 Handler 源码了,虽然还是有很多地方不理解,但相比之前已经理解了很多了,对于不理解的东西还是多看,书读百遍,其义自现,还是很有道理的,别忘了在看的时候做好笔记,哪怕现在理解的不是很正确,也要记录下来,下次再看的时候,对照着以前的笔记看,就会发现以前是哪里不理解,该怎么理解才对。今天就先看这些了,下次遇到问题再继续看吧!