13

クォーター/ハーフ/ピリオドの経過時間を追跡する必要があるスポーツ アプリを作成しています。経過時間は秒単位まで正確である必要があります。ユーザーが電源ボタンを押して明示的にデバイスをスリープ モードにした場合でも、ゲーム クロックは動作し続ける必要があります。

これを最初に試みたのは、Handler.postDelayed()を使用して 200 ミリ秒ごとにクロック ティックをトリガーし、WindowManager.LayoutParms.FLAG_KEEP_SCREEN_ONを使用して、画面のタイムアウトによって「クロック」が停止しないようにすることでした。しかし、電源ボタンを押してデバイスを手動でスリープ状態にすることで、このアプローチを回避できることをすぐに知りました。さらに、postDelayed() アプローチでは、明らかに run() メソッドで費やされた時間の結果として、クロック ドリフトが発生しています。実際の数値は依然として正確ですが、たとえば、ユーザーが簡単に理解できる 5 秒の境界に合わせる代わりに、関係するタイマーがドリフトし始め、理解できるユーザーの混乱を招きます。

少し調査した後、サービス、Java タイマーAlarmManager、およびPartialWakeLockを使用してタイマーを実装するためのテクニックを見つけました。サービス自体は、デバイスがスリープ状態になることに関連する問題を解決しません。Java タイマーは、サービスと同様に、デバイスがスリープ状態になる問題を解決しません。AlarmManager は良いアプローチのように思えますが、これは AlarmManager の適切な使用方法 (つまり、アラーム間の非常に短い間隔) ではないことを懸念しています。PartialWakeLock を使用することも有望に見えますが、それだけでは私が経験しているクロック ドリフトの問題には対処できません。

AlarmManager と PartialWakeLock の組み合わせを試してみます。アイデアは、AlarmManager がクロック ドリフトと戦うのに役立ち、PartialWakeLock がコードをシンプルに保つのに役立つ (指を交差させた) というものです。このアプローチにより、省電力、コードの複雑さ、およびユーザーの期待の間で合理的なバランスが得られることを願っています。どんなアドバイスでも大歓迎です。

ありがとう、

リッチ

4

2 に答える 2

4

上記の元の投稿に対する部分的な解決策があります。postDelayed()処理中の計算に費やされる時間に関連するクロック ドリフトにはまだ対処していませんが、一歩前進です。さらに、これは一見シンプルで、常に良い兆候です。

SystemClock.elapsedRealtime()を使用していたはずの SystemClock.uptimeMillis() を使用していたことがわかりました。2 つの違いは微妙ですが、重要です。

ご想像のとおり、私のソリューションでは、postDelayed() の呼び出し間の期間を累積することで、経過時間を追跡しています。上で述べたように、元の実装ではuptimeMillis()を使用していました。javadocを注意深く読むと、uptimeMillis()には「ディープ スリープ」状態 (ユーザーが電源ボタンを押したときなど) に費やされた時間が含まれていないことがわかります。ただし、lapsedRealtime()メソッドには、「ディープ スリープ」モードで費やされた時間が含まれます。ディープ スリープ サイクル全体で時間を追跡するために必要だったのは、uptimeMillis() の使用を経過リアルタイム() に置き換えることだけでし. 成功!AlarmManager、PartialWakeLock、またはその他のより複雑なものを使用する必要はありません。確かに、これらのメソッドにはまだ使用法がありますが、単純な経過時間クロックまたはタイマーを実装する場合はやり過ぎです。

次に取り組むべき問題は、postDelayed()処理に関連するゼロ以外の実行時間によって引き起こされるクロック ドリフトです。スレッドを生成して処理を行うことでこの問題が解決され、postDelayed()が多かれ少なかれ非同期呼び出しを模倣できるようになることを願っています。もう 1 つの方法は、 postDelayed() で費やされた時間を考慮して postDelayed() 遅延時間を調整することです。私の結果を投稿します。

関係のない話ですが、調査中にCommonsWare Warescriptionに対処しました。この問題についてこのソースからのアイデアを直接使用したことはありませんが、近い将来、Android の頼りになる情報源になると思います。私は本業で O'Reilly のサブスクリプションを取得していますが、CommonsWare の書籍は、少なくとも O'Reilly のリソースと同じか、それよりも優れた Android 開発に関する情報源であることがわかりました。また、O'Reilly Safari のリソースは非常に優れていることがわかりました。面白い...

乾杯、リッチ

于 2011-02-09T04:47:04.847 に答える