私は、デバイスのセンサーを常にポーリングするアプリを作成しており、頻繁にいくつかの統計をファイルに書き留める必要があります。これは、1 秒に 1 回の速さでも、1 分に 1 回の遅さでもかまいません。メソッドを使用Handler's
postDelayed()
するか、単にスケジュールする必要がありAlarmManager
ますか?
4 に答える
アプリがスタンバイで動作する場合は、AlarmManager
. そうでない場合Handler
。
AlarmManager
CPU をウェイクアップするため、バッテリーをさらに消費しますが、Handler
スタンバイでは動作しません。
以下のキーポイントに基づいてデザインを決定してください。
AlarmManager:
の利点はAlarmManager
、デバイスがディープ スリープ モード (CPU がオフ) の場合でも機能することです。アラームが発生するBroadcastReceiver
と、 と がヒットしonReceive
、ウェイク ロックが取得されます (またはWAKEUP
のようなタイプのアラームを使用した場合)。終了後、wake lock を解除します。RTC_WAKEUP
ELAPSED_TIME_WAKEUP
onReceive()
しかし、ほとんどの場合、それはうまくいきませんでした。そのため、私は独自の wake lock を取得onReceive()
し、最後にそれらを解放して、実際に CPU を取得できるようにしました。
機能しなかった理由は、複数のアプリケーションが同時にリソース (システムのサスペンドを防止するウェイクロックなど) を使用する場合、フレームワークがそれらのアプリケーション間で CPU 消費を分散させるためです。ただし、必ずしも均等ではありません。したがって、それが重要な場合は、wake lock を取得して処理を実行することをお勧めします。
タイマーとハンドラー:
Handler
タイマーはディープ スリープ モードでは機能しません。つまり、デバイスがスリープ状態の場合、タスク/ランナブルはスケジュールどおりに実行されません。スリープ中の時間はカウントされません。つまり、タスクを実行するために与えられた遅延は、アクティブ モード中にのみ計算されます。したがって、実際の遅延は、与えられた遅延 + ディープスリープで費やされた時間になります。
ポーリング間隔に依存すると思います。あなたの場合はかなり低いと思います(約数秒)ので、Handlerの方法を使用するか、Timerクラスを使用する必要があります。
AlarmManger ははるかに高レベルのサービスであり、このユース ケースを処理するにはより大きなオーバーヘッドが伴います。アラームがトリガーされたら、BroadcastReceivers で処理する必要があります。これは、これらのアラームの 1 つを処理するたびに、関心のあるセンサーのリスナーを登録する必要があることを意味しますが、これは非常に非効率的です。