前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Handler的消息延时是怎么实现的

Handler的消息延时是怎么实现的

作者头像
码农帮派
发布于 2021-01-12 06:56:46
发布于 2021-01-12 06:56:46
2.4K0
举报
文章被收录于专栏:码农帮派码农帮派
  • 消息延时做了什么特殊处理?
  • 是发送延时,还是消息处理延时?
  • 延时的精度如何?

通常我们使用Handler的消息延时都是调用sendMessageDelayed函数实现的,其中delayMillis是需要延时的毫秒。

通过跟踪sendMessageDelayed函数可以发现,最终是调用到了上面这个enqueueMessage方法,其中消息队列mMessages是单链表数据结果。

从上面的源码中可以看到,当前出入的消息msg时,首先判断mMessages消息队列中的第一个消息mMessages.prev,要是当前队列中消息为空,或者msg立即发送,则将该消息插到消息队列mMessages的头部;反之,则会在一个for的死循环中遍历消息队列并将传入消息msg插到单链表中合适的位置。事实上,消息队列是按照消息处理的时间when,按照从近到远的顺序排列的,最先要执行的任务放在消息队列的头部,依次排列。

从上面可以看到,Handler中sendMessageDelayed方法只是将消息按照要执行的先后顺序插入到消息队列中的,插入好了并不意味着就会按照设定的延时时间处理消息,那Handler时如何延时处理该消息的呢?

首先我们知道,Looper.loop()之后,线程就进入了消息监听的阶段:

当Handler中没有可用消息的时候,上面代码会一直阻塞在queue.next()的地方,直到消息返回,才会调用dispatchMessage进行消息的处理,要是返回的msg为空,那么Handler就会结束消息监听,不再监听任何消息。

我们来看看queue.next()函数:

上面是阻塞的从消息队列中获取可用消息的过程。其中nativePollOnce方法是一个native方法,其内部会根据传入的nextPollTimeoutMillis,在延迟这么长时间之后唤醒线程从消息队列中读取消息,内部调用的是epoll_wait方法。

我们知道当线程中没有新消息要处理的时候,线程处于休眠状态,当其他线程向Handler的消息队列中写入消息,这一动作并不会唤醒当前线程处理该消息,还需要向线程的eventfd中写入数据,从而唤醒休眠的线程开始处理数据,此处也是一样的,nativePollOnce函数内部会调用epoll_wait方法,设置超时时间为nextPollTimeoutMillis,epoll_wait在这个超时时间之后,就会唤醒线程,开始处理消息队列中的消息。

next方法中,每次会从消息队列mMessages中获取链表中头部的消息,要是头部消息的设定执行的时间要比当前时间大,说明消息队列中所有的消息都还没有到可执行的时间,这是因为消息队列中消息在插入消息队列的时候,按照执行时间的先后顺序已经排序好了。这种情况下,会计算出一个等待时间,传递到nativePollOnce函数中,让native层在这个等待时间之后再唤醒线程读取消息队列中的消息,进行消息处理。

Handler的消息延时的实现:

消息队列在插入消息的时候是按照消息的触发时间顺序排序的,先执行的消息放在单链表的头部,最后执行的消息放在单链表的尾部;

在消息执行的过程中,通过native层设置epoll_wait的超时事件,使其在特定时间唤醒线程开始出现消息。

关于延时精度:Handler的延时精度并不高,会受到前一个消息处理时间的影响,因为在Looper.loop()方法中,只有上一个消息被处理完之后,才会去queue中读取下一个消息。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农帮派 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Android Handler与Looper原理浅析
本文分析下Android的消息处理机制,主要是针对Handler、Looper、MessageQueue组成的异步消息处理模型,先主观想一下这个模型需要的材料:
看书的小蜗牛
2018/06/29
1.2K0
Android Handler与Looper原理浅析
面试问关于Handler的这些问题你知道吗?
Q :在线程中可以直接调用 Handler 无参的构造方法吗?在主线程和子线程中有没有区别? A:在主线程中可以;在子线程中会抛出RuntimeException, 需要先调用 Looper.prepare()。主线程在启动的时候已经在调用过Looper.prepare()。
103style
2022/12/19
2880
又一年对Android消息机制(Handler&Looper)的思考
Android消息机制对于每一个Android开发者来说都不陌生,在日常的开发中我们不可避免的要经常涉及这部分的内容。从开发角度来说,Handler是Android消息机制的上层接口,这使得在开发过程中只需要和Handler交互即可。Handler的使用过程很简单,通过它可以轻松的将一个任务切换Handler所在的线程中去执行。很多人认为Handler的作用是更新UI,这的确没错,但是更新UI仅仅是Handler的一个特殊的使用场景。具体来说是这样的;有时候需要再子线程中进行耗时的I/O操作,可能是读取文件或访问网络等。。。。。
静默加载
2020/05/31
1.1K2
Handler:Android 消息机制,我有必要再讲一次!
我们在日常开发中,总是不可避免的会用到 Handler,虽说 Handler 机制并不等同于 Android 的消息机制,但 Handler 的消息机制在 Android 开发中早已谙熟于心,非常重要!
Android架构
2019/07/24
4030
Handler,Message, MessageQueue 和 Looper
在开发过程中非主线程更新UI,第一个想到的就是通过Handler来刷新UI,那Handler是如何工作的呢? Handler Handler是消息处理器,负责Message消息的发送和处理。 mHa
艳龙
2021/12/16
2580
面试官带你学Android——面试中Handler 这些必备知识点你都知道吗?
在Android面试中,关于 Handler 的问题是必备的,但是这些关于 Handler 的知识点你都知道吗?
Android技术干货分享
2020/10/12
7100
面试官带你学Android——面试中Handler 这些必备知识点你都知道吗?
从 Android 开发到读懂源码 第07期:Message 机制源码解析
核心类就是 ThreadLocal ,它提供线程局部变量,每个线程都有自己独立的一份变量,通常是类中的 private static 字段,它们希望将状态与某一个线程相关联,在多线程编程中常用,比如 Android 的绘制同步机制 Choreographer 中也有使用。
数据库交流
2022/04/25
3860
从 Android 开发到读懂源码 第07期:Message 机制源码解析
Android Handler,Looper 与 MessageQueue 使用与分析
一个Handler允许发送和处理Message,通过关联线程的 MessageQueue 执行 Runnable 对象。 每个Handler实例都和一个单独的线程及其消息队列绑定。 可以将一个任务切换到Handler所在的线程中去执行。一个用法就是子线程通过Handler更新UI。
AnRFDev
2021/02/01
7850
Android Framework学习(八)之Handler消息机制(Native层)解析
在深入解析Android中Handler消息机制一文中,我们学习了Handler消息机制的java层代码,这次我们来学习Handler消息机制的native层代码。
老马的编程之旅
2022/06/22
1.2K0
Android Framework学习(八)之Handler消息机制(Native层)解析
Android全面解析之由浅及深Handler消息机制
关于Handler的博客可谓是俯拾皆是,而这也是一个老生常谈的话题,可见的他非常基础,也非常重要。但很多的博客,却很少有从入门开始介绍,这在我一开始学习的时候就直接给我讲Looper讲阻塞,非常难以理解。同时,也很少有系统地讲解关于Handler的一切,知识比较零散。我希望写一篇从入门到深入,系统地全面地讲解Handler的文章,帮助大家认识Handler。
huofo
2022/03/18
8340
Android全面解析之由浅及深Handler消息机制
Android Looper,Handler,Message,MessageQueue介绍
最近在看WMS代码,里面好多都涉及到Handler, Looper通信,相比Binder通信,Handler适用于线程间通信,并且没有Binder那么复杂,也容易理解,对于更新UI操作更是需要Handler,本篇就专门介绍下Handler相关内容,包括App层的使用,FWK和Native的具体实现,通过这块内容介绍, 可以对这块有一个清晰的认识。
一只小虾米
2022/10/25
8800
Android Looper,Handler,Message,MessageQueue介绍
Handler面试八问
线程启动之后,进入main()方法,在main()方法中进行线程的一些初始化,初始化工作完成之后,会调用Looper.loop()进行消息监听,而loop()方法是一个死循环,从而保证线程不会立即退出:
码农帮派
2021/01/28
1.2K0
「细品源码」 Android 系统的血液:Handler
作为 Android 开发者,相信对于 Handler 的使用早已烂熟于心。Handler 对于 Android 非常重要,可以说,没有它,Android App 就是一堆“破铜烂铁”,它就像 Android 的血液,穿梭在 App 的各个角落,输送养分。
开发的猫
2020/06/19
1K0
「细品源码」 Android 系统的血液:Handler
Android Handler机制8之消息的取出与消息的其他操作
这个方法已经在Android Handler机制4之Looper与Handler简介中说过了,我就重点说下流程,大体上分为6步
隔壁老李头
2018/08/30
1.5K0
Android Handler机制8之消息的取出与消息的其他操作
Android面试必备知识点:Android中Handler八大问题汇总
Handler机制几乎是Android面试时必问的问题,虽然看过很多次handler源码,但是有些面试官问的问题却不一定能够回答出来,趁着机会总结一下面试中所覆盖的handler知识点。
Android技术干货分享
2020/04/10
1.2K0
Android面试必备知识点:Android中Handler八大问题汇总
Handler 源码解析(Java 层)
从很早开始就认识到 Handler 了,只不过那时修为尚浅,了解的不够深刻,也没有应用自如。不过随着工作时间的增长,对 Handler 又有了更深层次的认识,于是有了这篇博客,希望尽可能的总结出多的知识点。
程序亦非猿
2019/08/16
4190
深入理解 Android 消息机制原理
导语: 本文讲述的是Android的消息机制原理,从Java到Native代码进行了梳理,并结合其中使用到的Epoll模型予以介绍。 Android的消息传递,是系统的核心功能,对于如何使用相信大家都
汪毅雄
2017/11/08
2K0
深入理解 Android 消息机制原理
看完这篇,别再说你不了解 Handler 消息机制了
原文链接 https://juejin.cn/post/7291935623476183067
GeeJoe
2023/10/24
7630
看完这篇,别再说你不了解 Handler 消息机制了
笔记:安卓App消息处理机制
内容简述 类似Binder机制,MessageQueue、Looper也有底层的C++实现,涉及文件管道和驱动等。 以下仅从Java层的Looper、Handler和MessageQueue等相关类
用户1172465
2018/01/08
1.2K0
Handler 消息机制原来解析
分为同步消息、异步消息、屏障消息。但是异步消息和屏障消息的相关API都是隐藏的,需要通过反射才能使用。
李林LiLin
2020/12/21
9770
推荐阅读
相关推荐
Android Handler与Looper原理浅析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档