From 6703bd2146e53b011710b3ec1beb60dbb824bd5c Mon Sep 17 00:00:00 2001 From: Omooo <869759698@qq.com> Date: Wed, 27 May 2020 10:01:02 +0800 Subject: [PATCH] =?UTF-8?q?Update=20Handler=20=E6=B6=88=E6=81=AF=E6=9C=BA?= =?UTF-8?q?=E5=88=B6.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- blogs/Android/Handler 消息机制.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/blogs/Android/Handler 消息机制.md b/blogs/Android/Handler 消息机制.md index 3bcb173..8a5726d 100644 --- a/blogs/Android/Handler 消息机制.md +++ b/blogs/Android/Handler 消息机制.md @@ -525,6 +525,19 @@ MessageQueue 有两个重要方法,一个是 enqueueMessage 用于存消息, } ``` +5. 你知道延时消息的原理嘛? + + 发送的消息 Message 有一个属性 when 用来记录这个消息需要处理的时间,when 的值:普通消息的处理时间是当前时间;而延时消息的处理时间是当前时间 + delay 的时间。Message 会按 when 递增插入到 MessageQueue,也就是越早时间的排在越前面。 + + 在取消息处理时,如果时间还没到,就休眠到指定时间;如果当前时间已经到了,就返回这个消息交给 Handler 去分发,这样就实现处理延时消息了。休眠具体时间是在 MessageQueue 的 nativePollOnce 函数中处理,该函数的第二个参数就是指定需要休眠多少时间。 + +6. 主线程的 Looper#loop() 在死循环,会很消耗资源嘛? + + 如果没有消息时,就会调用 MessageQueue 的 nativePollOnce 方法让线程进入休眠,当消息队列没有消息时,无限休眠;当队列的第一个消息还没到需要处理的时间时,则休眠时间为 Message.when - 当前时间。这样在空闲的时候主线程也不会消耗额外的资源了。而当有新消息入队时,enqueueMessage 里会判读是否需要通过 nativeWake 方法唤醒主线程来处理新消息。唤醒最终是通过往 EventFd 发起一个写操作,这样主线程就会收到一个可读事件进而从休眠状态被唤醒。 + +7. 你知道 IdleHandler 嘛? + + IdleHandler 是通过 MessageQueue.addIdleHandler 来添加到 MessageQueue 的,前面提到当 MessageQueue.next 当前没有需要处理的消息时就会进入休眠,而在进入休眠之前呢,就会调用 IdleHandler 接口里的 boolean queueIdle 方法。这个方法的返回 true 则调用后保留,下次队列空闲时还会继续调用;而如果返回 false 调用完就被 remove 了。可以用到做延时加载,而且是在空闲时加载。 #### 总结