handler.postDelayed() 的执行过程

今天做项目看到这段代码时产生了一些疑惑,又打开 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 源码了,虽然还是有很多地方不理解,但相比之前已经理解了很多了,对于不理解的东西还是多看,书读百遍,其义自现,还是很有道理的,别忘了在看的时候做好笔记,哪怕现在理解的不是很正确,也要记录下来,下次再看的时候,对照着以前的笔记看,就会发现以前是哪里不理解,该怎么理解才对。今天就先看这些了,下次遇到问题再继续看吧!

你可能感兴趣的:(handler.postDelayed() 的执行过程)