Java android-handler.postDelayed它是如何实现延迟的
对于任何必须延迟的任务,我一直在使用:Java android-handler.postDelayed它是如何实现延迟的,java,android,multithreading,Java,Android,Multithreading,对于任何必须延迟的任务,我一直在使用:Handler.postDelayed(Runnable r,Long Delay),但我最近才看到文档,它说: 使可运行r添加到消息队列中,在经过指定的时间后运行。runnable将在该处理程序所连接的线程上运行。时基为SystemClock.uptimeMillis()。在深度睡眠中花费的时间将增加执行的额外延迟 我有两个困惑: 是通过将Runnable添加到MessageQueue 在指定的延迟时间之后 或者 是否立即添加可运行,并将函数延迟 指定的时
Handler.postDelayed(Runnable r,Long Delay)
,但我最近才看到文档,它说:
使可运行r添加到消息队列中,在经过指定的时间后运行。runnable将在该处理程序所连接的线程上运行。时基为SystemClock.uptimeMillis()。在深度睡眠中花费的时间将增加执行的额外延迟
我有两个困惑:
Runnable
添加到MessageQueue
在指定的延迟时间之后
或者可运行
,并将函数延迟
指定的时间。如果是这样,那么必须有一种机制
Runnable将退出队列并放在其他位置,以便其他项目可以进入
可以处理队列。Runnable是如何延迟的,它是如何延迟的
MessageQueue
是否在此延迟期间维护runnable立即添加到消息队列中,可以在
postDelayed->sendMessageDelayed->sendMessageAtTime
public boolean sendMessageAtTime(Message msg, long uptimeMillis)
{
boolean sent = false;
MessageQueue queue = mQueue;
if (queue != null) {
msg.target = this;
sent = queue.enqueueMessage(msg, uptimeMillis);
}
else {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
}
return sent;
}
queue.enqueueMessage
运行(;;)的来延迟回调。
在这个连续循环中,检查消息的执行时间。您可以在源代码中看到这一点,我们称之为Handler
的结构运行时带有Looper
,其中包含MessageQueue
。调用Handler.post(runnable)
会为MessageQueue
创建一条新消息,并将其置于队列的最后一个位置,其时间设置为SystemClock.uptimeMillis()
Looper
始终循环检查消息,如果有消息且目标时间已过,它将在消息中执行Runnable
澄清:
Handler.post(runnable)
发送带有SystemClock.uptimeMillis()
的消息,其中在下一次检查时,新的SystemClock.uptimeMillis()
将大于消息的执行时间,从而允许循环器
获取并执行runnable
现在,如果您使用Handler.postDelayed(runnable,delay)
它使用SystemClock.uptimeMillis()+delay
发布消息,其中延迟以毫秒为单位,我们现在将其称为messageTime
。活套的作用是什么?它检查消息,如果SystemClock.uptimeMillis()
小于messageTime
,它将跳过执行。Looper总是循环,因此有一段时间SystemClock.uptimeMillis()
实际上比messageTime
大,此时runnable可以执行
除非调用Handler.postAtFrontOfQueue(runnable)
,否则调用总是放在队列的底部,而不是顶部
最后确定:
Handler.post(可运行)
-->messageTime=SystemClock.uptimeMillis()
Handler.postDelayed(runnable,delay)
-->messageTime=SystemClock.uptimeMillis()+delay
Looper在SystemClock.uptimeMillis()>=messageTime
的位置执行可运行文件。这就是它的要点。只是一个猜测:2。当runnable到达队列的前端时,将计算其执行时间,如果它在将来被回传到队列的后端,那么当作业被延迟时,队列的结构如何?队列被构造为一个链表,然后在
时用进行迭代和检查(包含要执行的时间)消息
对象中的变量。带有SystemClock.upItemMillis()+delay
的消息是否放在队列末尾?