文档章节

Handler sendMessageDelayed()/postDelayed()机制详解

o
 osc_mervd488
发布于 2018/04/24 14:30
字数 678
阅读 9
收藏 0

精选30+云产品,助力企业轻松上云!>>>

http://blog.csdn.net/zhanglianyu00/article/details/70842494

 

Handler调用关系整理如下:

 

post()/postDelayed()/sendMessage()->sendMessageDelayed()->sendMessageAtTime()->enqueueMessage()

postAtTime()->sendMessageAtTime()->enqueueMessage()

postAtFrontOfQueue()->sendMessageAtFrontOfQueue()->enqueueMessage()

最后都以enqueueMessage()告终

enqueueMessage()->MessageQueue.enqueueMessage(Message msg, long when)

如前所述,这时候when已经转化成绝对系统时间。

 

enqueueMessage(Message msg, long when)这个方法比较简单,采用线程安全的方式将Message插入到消息队列中,插入的新消息有三种可能成为消息队列的head:

(1)消息队列为空;

(2)参数when为0,因为此时when已经转成绝对时间,所以只有AtFrontOfQueue系列的API才会满足这个条件;

(3)当前的head Message执行时间在when之后,即消息队列中无需要在此Message之前执行的Message。

 

接下来就要看看消息循环(Looper)如何使用when,这是本文问题的关键。关键的方法,Looper.loop(),启动线程消息循环:

根据Looper.loop()方法,我们看一看出取下一个消息的实际执行时间取决于上一个消息什么时候处理完。

再看MessageQueue.next()做了什么。

看到next()实际上也有一个for(;;),而出口只有两个:消息队列已经退出,返回null;找到了一个合适的消息,将其返回。如果没有合适的消息,或者消息队列为空,会block或者由IdleHandler处理。

可以看到,如果在消息队列中顺序找到了一个消息msg(前文分析过,消息队列的插入是由when顺序排列,所以如果当前的消息没有到执行时间,其后的也一定不会到),当前的系统时间小于msg.when,那么会计算一个timeout,以便在到执行时间时wake up;如果当前系统时间大于或等于msg.when,那么会返回msg给Looper.loop()。所以这个逻辑只能保证在when之前消息不被处理,不能够保证一定在when时被处理。很好理解:

 

(1)在Loop.loop()中是顺序处理消息,如果前一个消息处理耗时较长,完成之后已经超过了when,消息不可能在when时间点被处理。

(2)即使when的时间点没有被处理其他消息所占用,线程也有可能被调度失去cpu时间片。

(3)在等待时间点when的过程中有可能入队处理时间更早的消息,会被优先处理,又增加了(1)的可能性。

所以由上述三点可知,Handler提供的指定处理时间的api诸如postDelayed()/postAtTime()/sendMessageDelayed()/sendMessageAtTime(),只能保证在指定时间之前不被执行,不能保证在指定时间点被执行。

 

 

 

 

 

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
【转】从源码分析Handler的postDelayed为什么可以延时?

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/aliankg/article/details/70842494 Thread/Hander/Looper是Android在Java线程基础之上提供的线程通信/消息处理...

osc_zfz9ur01
2018/12/16
2
0
postDelayed, sendMessageAtTime等handler发送消息方法总结

post方法在View类和Handler类中都有,我们经常使用。 比如listview滑动到某个指定位置: 软键盘弹出: scrollview自动滑动到底部: 甚至,在post方法中获取控件宽高: 那么,View类中的post方...

imutlxy
2016/05/04
478
0
post sendMessage

前言 post方法在View类和Handler类中都有,我们经常使用。 比如 listview滑动到某个指定位置: 软键盘弹出: scrollview自动滑动到底部: 甚至,在post方法中获取控件宽高: 那么,View类中的...

imutlxy
2016/06/27
2
0
Handler 使用详解

极力推荐文章:欢迎收藏Android 干货分享 #####阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android 本篇文章主要介绍 开发中的部分知识点,通过阅读本篇文章,您将收获以下内容:...

osc_2h38v7rr
2019/08/06
1
0
Android 开发日志- Handler详解(一)

一个Handler允许你发送和处理消息(Message)以及与一个线程的消息队列相关的Runnable对象。每个Handler实例都和单个线程以及该线程的消息队列有关。当你创建了一个新Handler,它就会和创建它...

Neo丶
2015/07/10
3
0

没有更多内容

加载失败,请刷新页面

加载更多

setShadowLayer阴影与SetMaskFilter发光效果

一、setShadowLayer构造函数 public void setShadowLayer(float radius, float dx, float dy, int color) radius:模糊半径,radius越大越模糊,越小越清晰,但是如果radius设置为0,则阴...

IamOkay
27分钟前
31
0
做儿媳的,千万不要把婆婆当亲妈看

我和老公结婚有三四个年头了,还生育了两个调皮可爱的孩子。在别人眼里,我就像掉进了福窝里一样。然而我有时候在老公面前耍小性子,撒娇卖萌什么样的,婆婆却指责我不守妇道。 结婚起初婆家...

创业hzcya
37分钟前
6
0
多线程之线程部分

① 进程与线程 程序、进程、线程、协程的概念 程序: 用某种语言编写的一组指令的集合,即指一段静态的代码; 进程:简单地说就是一个正在执行的程序或应用,是资源分配的最小单位; 线程:线...

Arno_pei
49分钟前
0
0
08VulKan——描述符布局、缓冲、描述符池和描述符集

整体思想: 对于一些所有顶点都共享的属性,比如顶点的变换矩阵,将它们作为顶点属性为每个顶点都传递一份显然是非常浪费的 。VulKan提出使用资源描述符解决这种全局变量, 描述符是用来在着...

黑白双键
今天
7
0
将分段视频合并

环境 操作系统:Ubuntu Kylin 优麒麟 20.04 LTS 适用架构:AMD64、ARM64(鲲鹏、飞腾) 方法 将下载的视频分片段放入同一个文件夹。按片段排序的文件名汇入list.txt。 ls qq_video*.mp4 | s...

chipo
今天
18
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部