2011-02-07 65 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你不會看到任何漂移,但你的電池將耗盡 豐富