Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java android-handler.postDelayed它是如何实现延迟的_Java_Android_Multithreading - Fatal编程技术网

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
    的消息是否放在队列末尾?