1. ホーム
  2. android

[解決済み] Androidで定期的なタスクのスケジューリングを行う

2022-08-03 18:09:38

質問

アプリがフォアグラウンドである限り、専用サーバーにプレゼンスを送信するタスクを繰り返し行うアプリを設計しています。

Web で検索したところ、いくつかの異なるアプローチを目にし、これを行う最良の方法は何かを知りたいと思いました。

サーバー コールをスケジュールする最良の方法は何ですか。

私が見たオプションは

  1. タイマー .

  2. ScheduledThreadPoolExecutor (スケジューリングされたスレッドプールエクセキュータ) .

  3. サービス .

  4. ブロードキャストレシーバに アラームマネージャ .

あなたの意見は?

EDITです。

私がこれを必要とする理由は、リモートサーバーにすべてのユーザーのアクションを送信するチャットベースのアプリのためです。

すなわち、ユーザーがメッセージを入力している、ユーザーがメッセージを読んでいる、ユーザーがオンラインである、ユーザーがオフラインであるなどです。

これは、私が他の人とチャットルームを開いているので、私が何をしているかを知る必要があるため、一定時間ごとに、私が何をしているかをサーバーに送信する必要があることを意味します。

Whatsappメッセージのフィードバック機構に似ています。

EDIT #2です。

定期的なタスクのスケジュールは、ほとんど常に JobScheduler API (または FirebaseJobDispatcher で読むことができるように、バッテリーの消耗の問題を防ぐために、下位のAPIでは バイタルセクション を参照してください。

EDIT #3です。

FirebaseJobDispatcherは非推奨となり、以下のように置き換えられました。 Workmanager に置き換えられました。これは JobScheduler の機能も取り入れています。

どのように解決するのですか?

私は確信していないが、私の知識として私は私の見解を共有しています。私は常に私が間違っている場合、最高の答えを受け入れる。

アラーム管理者

アラーム・マネージャは、アラーム・レシーバの onReceive() メソッドが実行されている間、CPU ウェイクロックを保持します。これにより、ブロードキャストの処理が終了するまで、携帯電話がスリープしないことが保証されます。一度 onReceive() が返されると、アラームマネージャーはこのウェイクロックを解放します。つまり、場合によっては onReceive() メソッドが完了すると同時にスリープする場合があるということです。もし、あなたのアラーム受信機が Context.startService() を呼び出した場合、要求されたサービスが開始される前に携帯電話がスリープする可能性があります。これを防ぐために、あなたの BroadcastReceiverService は、サービスが利用可能になるまで電話が動作し続けることを保証するために、個別のウェイクロックポリシーを実装する必要があります。

注意: アラーム マネージャーは、アプリケーションが現在実行されていない場合でも、アプリケーション コードを特定の時間に実行させたい場合を想定しています。通常のタイミング操作 (tick、タイムアウトなど) では、Handler を使用する方が簡単ではるかに効率的です。

タイマ

timer = new Timer();

    timer.scheduleAtFixedRate(new TimerTask() {

        synchronized public void run() {

            \\ here your todo;
            }

        }, TimeUnit.MINUTES.toMillis(1), TimeUnit.MINUTES.toMillis(1));

Timer にはいくつかの欠点がありますが、それを解決するのが ScheduledThreadPoolExecutor . だから、それは最良の選択ではありません。

ScheduledThreadPoolExecutor (スケジューラードスレッドプールエクセキュータ) .

を使うことができます。 java.util.Timer または ScheduledThreadPoolExecutor (推奨) を使って、バックグラウンドのスレッドで定期的にアクションを発生させるようスケジュールします。

以下は後者を使ったサンプルです。

ScheduledExecutorService scheduler =
    Executors.newSingleThreadScheduledExecutor();

scheduler.scheduleAtFixedRate
      (new Runnable() {
         public void run() {
            // call service
         }
      }, 0, 10, TimeUnit.MINUTES);

ということで、私は ScheduledExecutorService

しかし、アプリケーションの実行中に更新が行われる場合についても考えてみてください。 Timer を使うか、他の回答で提案されているように、より新しい ScheduledThreadPoolExecutor . アプリケーションが動作していないときでも更新される場合は AlarmManager .

アラームマネージャは、アプリケーションが現在実行されていなくても、特定の時刻にアプリケーションのコードを実行させたい場合を想定しています。

アプリケーションが停止しているときに更新することを計画している場合、10 分に 1 回はかなり頻繁であり、したがって、少し電力を消費しすぎる可能性があることに注意してください。