2011-02-07 44 views
9

我正在写一个需要跟踪季度/半/周期的运行时间的运动应用程序。经过的时间需要准确到秒。即使用户通过按电源按钮明确地将设备置于睡眠模式,游戏时钟也需要继续运行。涉及使用Handler.postDelayed()触发时钟滴答每200ms和WindowManager.LayoutParms.FLAG_KEEP_SCREEN_ON,确保了“时钟”不是由屏幕超时停止设备睡眠时有效的Android定时器

我在第一次尝试。但是我很快就了解到可以通过按电源按钮手动将设备置于睡眠状态来绕过此方法。另外,postDelayed()方法正在经历一些时钟漂移,显然是run()方法花费的时间的结果。实际的数字仍然是准确的,但并不是一致的,例如,在用户容易理解的5秒边界上 - 所涉及的定时器开始漂移,导致一些可理解的用户混淆。

经过一番研究,我发现使用服务的技术,java timers,AlarmManagerPartialWakeLock来实现定时器。服务本身不能解决与设备进入睡眠相关的问题。 Java计时器(如服务)不能解决设备进入睡眠状态的问题。 AlarmManager似乎是一种很好的方法,但我担心这不适合使用AlarmManager(即警报间隔非常短)。使用PartialWakeLock也看起来很有希望,但它本身并没有解决我遇到的时钟漂移问题。我将尝试AlarmManager和PartialWakeLock的组合。这个想法是,AlarmManager将帮助对抗时钟漂移和PartialWakeLock,以帮助保持代码简单(手指交叉)。我希望这种方法能够在节能,代码复杂度和用户期望之间取得合理的平衡。任何意见是极大的赞赏。

感谢,

丰富

+0

。 – NitZRobotKoder 2014-04-03 01:37:07

回答

4

我有上面部分解决了我原来的职位。它尚未解决与处理期间计算花费的时间相关的时钟漂移,但它向前迈进了一步。另外,它看似简单,总是一个好兆头。

原来我用SystemClock.uptimeMillis()时,我应该一直在使用SystemClock.elapsedRealtime()。 2之间的差别很微妙,但很重要。

正如您所预料的那样,我的解决方案通过累计调用postDelayed() - (即,elapsed time = elapsedTime + lastClockInterval)之间的持续时间来跟踪已用时间。如上所述,原始实现使用uptimeMillis()。仔细阅读javadoc reveals that uptimeMillis()不包括花费在“深度睡眠”中的时间,例如,当用户按下电源按钮时。但是,方法确实包括花费在“深度睡眠”模式中的时间。在深度睡眠周期中追踪时间所需的全部内容是用uptimeMillis()elapsedRealtime()。成功!不需要使用AlarmManager,PartialWakeLock或其他任何更复杂的事情。当然,这些方法仍然有用处,但是在实现一个简单的经过时间的时钟或定时器时它们是过度的。

下一个需要解决的问题是与处理postDelayed()相关的非零执行时间导致的时钟漂移。我希望产生一个线程来处理这个问题,允许postDelayed()或多或少模仿一个异步调用。另一种方法是调整延迟时间以考虑postDelayed()中花费的时间。我会发布我的结果。

在一个不相关的记录中,在我的调查过程中,我把自己对待一个CommonsWare Warescription。虽然我没有直接使用这个来源的任何想法来解决这个问题,但我确实认为这将成为我在可预见的将来的Android开源信息源。我通过我的日常工作获得了O'Reilly的订阅,但是我发现CommonsWare的书籍至少与作为O'Reilly资源的Android开发相关的信息来源一样好。我发现O'Reilly Safari的资源非常好。有趣的...

干杯,使用PartialWakeLock你不会看到任何漂移,但你的电池将耗尽 丰富

相关问题