问题记录 Android Handler —— 使用sendEmptyMessageDelayed计时会产生误差

问题

在一个项目中,使用主线程的handler.sendEmptyMessageDelayed(what, 1000),进行210秒的倒计时,最后发现误差竟然达30秒

分析

打印日志,发现每次处理计时handler消息的时间间隔大概是1.3s,足足有了0.3s的延迟,每次这样累积下来,会出现一个极大的误差。

猜测有可能是处理这条消息的逻辑时耗时了, 比如0.3s后才执行到handler.sendEmptyMessageDelayed(1000, 1000),于是改成先发送延迟消息,再处理逻辑

case 1000:

handler.sendEmptyMessageDelayed(1000, 1000);
// 处理大量逻辑...
break;

(不知道对你有没有用, 对我没卵用~)

误差的原因在于收到消息,到重新发出消息的时间,并不是瞬间完成的,这里面有很多逻辑处理的时间,即使没有逻辑处理的时间,handler本身也是耗损性能的,当UI线程处理的逻辑较多时,这个误差会来得更明显一些

解决:

使用sendEmptyMessageAtTime,在指定的时间点发出这条消息

case 1000:
long now = SystemClock.uptimeMillis();
long next = now + (1000 - now % 1000);
handler.sendEmptyMessageAtTime(0x1000, next);
// 处理大量逻辑
break;

为什么呢?假设now= 0,使用delay延迟1000ms时,因为各种损耗,假设1300毫米后才能处理这条消息,那么第一次收到消息时,时间为now = 1300,现在next = 1300 + (1000 - 1300 % 1000) = 2000,那我指定时间为2000时发这条消息,比原本提前了300ms发送补偿这个误差(原本每次延迟1000ms发送,现在相当于 (2000-1300)700ms后就发送这条消息)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值