老生常谈的Handler还是会在工作中给自己惊喜。最近在一次日常的转测用例执行过程中,突然发现有个请求被立刻移除了。查看了下代码记录才发现是使用Handler#postDelay传入的延迟时间。
Handler#postDelay传入的时间是以设备的持续活跃时间为基准的。即以SystemClock#uptimeMillis为参考,之所以注释中这样写,是因为Handler在计算延时时间时,是以SystemClock#uptimeMillis + 传入的延时时间来通知消息队列的。并且handler还很贴心的对延迟时间做了溢出判断,方便开发们意识到自己传错值了。


这种处理其实存在两个隐患:
如果设备存在不规则的休眠状态,那么你设置的延时处理操作将被大大延后触发。即如果你的业务要求一个规律性的间断操作的话,这个效果将会被大打折扣。
如果你传入了一个过大的延迟时间,就容易造成数值溢出问题,从而导致延迟处理操作被立即执行。比如下图中 传入数值超过了Long.MAX_VALUE后就会因生成一个负值而被handler默认更改为0。

针对隐患1,android一直在限制设备休眠期间的操作,SystemClock#uptimeMillis不会统计到休眠时间,但是休眠期间,handler也不会被执行操作。这是一种变相的延迟。
针对隐患2,因为大多时候我们不会可以去传入一个过大的long值,但也不排除某天有业务场景确实需要这样做。在这种场景下,也最好使用sendMessageAtTime(),否者就会跟你打算使用达克罗宁却还没有起效一样失落。