更改系统时间时运行计时器会发生什么?
我有一个Android应用程序,我使用handler.postDelayed(Runnable,interval)在间隔结束时发布要调用的Runnable(run()方法)。
我的问题是: 如果底层系统时间在外部改变会发生什么? 我的印象是发布仍然发生,但在系统时间改变时倒计时再次开始......有人可以在这里点亮一些光吗?
如果时间变化是向前还是向后,行为会改变吗?
答案 0 :(得分:1)
首先,您应该知道Handler
基于SystemClock.uptimeMillis()
。
Handler
,sendMessageDelayed
等sendEmptyMessage
的sendMessageXXX()方法都使用以下方法:
//calcute the milliseconds we hope to handle the message since the system was booted
sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis)
然后,时间间隔值SystemClock.uptimeMillis() + delayMillis
将保留在Message
的字段when
中,我们将邮件放入MessageQueue
等待Looper
查看它。
当looper从队列中获取下一条消息时,它会将SystemClock.uptimeMillis()
与msg.when
进行比较,以判断消息是否准备就绪。如果下一条消息未准备好,它将设置超时唤醒直到msg准备就绪。
其次,您将SystemClock.uptimeMillis()
与System.currentTimeMillis()
混淆。以下是this post文档的一部分,它解释了这两个概念:
SystemClock.uptimeMillis()
以毫秒为单位计算。当系统进入深度睡眠状态(CPU关闭,显示较暗,设备等待外部输入)时,此时钟停止,但不受时钟缩放,空闲或其他省电机制的影响。这是大多数间隔时间的基础,例如Thread.sleep(millls),Object.wait(millis)和System.nanoTime()。该时钟保证是单调的,当间隔不跨越设备睡眠时,适用于间隔定时。 System.currentTimeMillis()
是标准的“墙”时钟(时间和日期),表示自纪元以来的毫秒数。挂钟可以由用户或电话网络设置(请参阅setCurrentTimeMillis(long)),因此时间可能会不可预测地向后或向前跳转。只有在与实际日期和时间对应很重要时,例如在日历或闹钟应用程序中,才应使用此时钟。间隔或经过时间测量应使用不同的时钟。如果您正在使用System.currentTimeMillis(),请考虑侦听ACTION_TIME_TICK,ACTION_TIME_CHANGED和ACTION_TIMEZONE_CHANGED Intent广播,以找出时间的变化。