设备处于低功耗模式时 SystemClock.elapsedRealtime() 漂移

Posted

技术标签:

【中文标题】设备处于低功耗模式时 SystemClock.elapsedRealtime() 漂移【英文标题】:SystemClock.elapsedRealtime() drift when the device is in low-power mode 【发布时间】:2012-06-27 17:14:21 【问题描述】:

根据 API 文档以及之前的 SO threads,SystemClock.elapsedRealtime() 应该即使在设备处于睡眠状态时也能保持准确的时间。这不是我观察到的。

我编写了一个简单的时钟,它位于while (true) 循环中,并根据SystemClock.elapsedRealtime() 的值更新屏幕上的时间。如果我同步两个设备上的时钟,例如通过 NTP,然后继续在其中一台设备上打开和关闭屏幕几次,显示的时间将漂移最多 +/- 0.7 秒。 (这只发生在手机未连接到外部电源时,因此睡眠模式可能是这里的罪魁祸首)。

这正常吗?这是android中的错误吗?有没有办法在睡眠/唤醒周期中保持约 20 毫秒的计时精度?

【问题讨论】:

【参考方案1】:

我也遇到了同样的问题,所以今晚我尝试将我的计时方法从 SystemClock.elapsedRealtime() 更改为 System.currentTimeMillis()。到现在为止还挺好。当我点击关闭应用程序并返回时,时间并没有漂移。 我已经在服务中使用 Runnable 对其进行了测试。我目前正在主要活动中使用 Runnable 对其进行测试,并在应用程序失去焦点时使用 sharedprefs 来存储所有内容。 我还没有决定这两种方法中哪一种最好——但currentTimeMillis 似乎没有受到elapsedRealtime 的漂移时间问题的影响。

我知道 google 不建议使用 currentTimeMillis 进行计时,但它似乎更适合在应用失去焦点时保持正确的时间。

【讨论】:

谢谢,看来你是对的,就漂移而言,使用 currentTimeMillis() 比 elapsedRealtime() 工作得更好(但它似乎仍然有点漂移)【参考方案2】:

我有一个应用程序每分钟与服务器通信一次。它通过在启动时记录服务器时间和 SystemClock.elapsedRealtime() 然后使用 elapsedRealtime 计算服务器时间来同步设备时钟和服务器时钟(我这样做是因为设备本身从网络同步时间而 #### 不能完全值得信赖)。

在一周的时间内,在 Galaxy Tab 2 上运行时,SystemClock.elapsedRealtime() 比服务器时钟慢了几分钟两小时。我的日志显示漂移的速度不是恒定的,因此设备的使用方式确实会影响它。

虽然 API 要求时钟提供单调的时间,但它并不能保证准确性。因此,它不是长时间准确记录时间的有用方法。

【讨论】:

以上是关于设备处于低功耗模式时 SystemClock.elapsedRealtime() 漂移的主要内容,如果未能解决你的问题,请参考以下文章

如何从处于低功耗状态的 USB 设备获取字符串描述符?

总结:低功耗蓝牙常见的4种工作模式

iPad应用程序崩溃导致executeFetchRequest:错误:并且设备处于低功耗状态

FreeRTOS 低功耗之睡眠模式

资产监测设备时,DTR进入低功耗模式

STM32F0系列——停机模式(低功耗)