Handler如何做到延迟发送

Handler 的延迟发送是依靠

nativePollOnce(ptr, nextPollTimeoutMillis);

这个方法中的nextPollTimeoutMills 表明了阻塞等待时间。
nextPollTimeoutMillis = (int)Math.min(msg.when - now, Interge.MAX_VALUE);

原理:
当sendMessage 时,enququeMessage()@MessageQueue 会将消息按照按照实际执行时间顺序(即msg.when)插入到队列,然后执行nativeWake()唤醒,随后执行到next()@MessageQueue 中的nativePollOnce()处,这里是一个 for 死循环,唤醒后计算出根据now 和msg.when,如果now < msg.when 则计算出nextPollTimeoutMillis,下一个循环赋值给nativePollOnce(ptr,nextPollTimeoutMillis),告诉阻塞时间。
【Handler如何做到延迟发送】其实 Java 层的 Handler 只是利用到了 native 层的 NativeMessageQueue和 native 层的 Looper 来完成阻塞和唤醒工作。消息队列的插入和消息的读取都是在 Java 层完成的
。当MessageQueue 在nativePollOnce()被nextPollTimeoutMillis 阻塞时,当有另外一个消息入队进行唤醒时,nativePollOnce()的阻塞状态立即被唤醒,然后进行处理消息,当发现now < msg.when 时,根据新的阻塞时间进行等待。因为消息在入队时根据msg.when 进行排列了。

    推荐阅读