web-dev-qa-db-ja.com

ジョブスケジューラとバックグラウンドサービス

毎分バックグラウンドで実行する機能Aを備えたアプリがあります。機能Aは、アプリがデータベースに接続し、データを読み取り、デバイスの現在の場所を取得し、それに基づいて条件を確認し、条件が真の場合、ユーザーにステータスバー通知を送信する必要があることですアプリのUIが表示される通知をクリックすると、何かが起こります。
このバックグラウンドタスクは、アプリの使用、終了、終了に関係なく、アプリスタックにあるかどうかにかかわらず通知を表示するfacebookやWhatsappなど、毎分恒久的に実行する必要があります。
今、検索して、AndroidがJob SchedulerバックグラウンドサービスAlarmManagerおよびHandlers
しかし、それらについて読むほど、私には文が矛盾しているように見えます。

  1. ハンドラーについては、長い遅延のために存在せず、システムの再起動後に終了することを読みました。だから、彼らは私の仕事にふさわしくないでしょう。
  2. ただし、AlarmManagerは、システムの再起動後も許可されている場合に存在し、アプリを再実行できるため、AlarmManagerは問題の良い候補のようです。ただし、 Android Documentation では、Alarm Managerは特定の時間(目覚まし時計など)に実行する必要があるタスクに使用することを目的としています。しかし、私のタスクは毎分実行する必要があります。
  3. 次に、バックグラウンドサービスがあります。これは、私が読んだバックグラウンドでのダウンロードなどのタスクに向いており、説明したことを行うためのものではありません。
  4. JobSchedulerは、恒久的に実行する必要があるタスクではなく、アイドルやネットワークなしなどの特定の制約を満たすタスク向けのようです。前半で説明したタスクのために
28
Code Pope

毎分バックグラウンドで実行する機能Aを備えたアプリがあります。

Dozeモード(およびアプリの他の部分によってはアプリスタンバイ)により、数億のAndroidデバイス、Android 6.0以降を実行しているデバイスでは発生しません。 )。

ただし、AlarmManagerは、システムの再起動後でも許可されているため、AlarmManagerは問題の良い候補のようです。

いいえそうではありません。再起動後、AlarmManagerでスケジュールされたすべてのアラームを再スケジュールする必要があります。

アラームマネージャは、特定の時間に実行する必要があるタスクに使用することを目的としています

AlarmManagerは繰り返しオプションをサポートしています。

これは、私が読んだバックグラウンドでのダウンロードなどのタスクに向いており、説明したことを行うためのものではありません。

Serviceは、使用するソリューションに不可欠です。

JobSchedulerは、恒久的に実行する必要があるタスクではなく、アイドルやネットワークなしなどの特定の制約を満たすタスク用のようです

JobSchedulerは、AlarmManagerと同様に、繰り返しジョブをサポートします。

したがって、これらの(または存在する場合は他の)のどれを最初の部分で説明したタスクに使用することをお勧めしますか

デバイスがDozeモードに入ると、画面がオフになってから1時間以内にAndroid 6.0+で1分ごとに実行できないため、いずれも使用しないでください。代わりに、1日に数回のバックグラウンド作業だけが必要になるようにアプリを再設計するか、アプリの作成に煩わされないようにします。

28
CommonsWare

MinSdkVersion = 21の場合、Android 5.0で導入された最新のJobScheduler AP​​Iを使用できます。

また、 https://github.com/firebase/firebase-jobdispatcher-Android があります。これには、インストール済みのGoogle Play minSdkVersion = 9が必要です。

ただし、このライブラリを使用することをお勧めします https://github.com/evernote/Android-job ここで、Androidバージョンに応じて、JobSchedulerGcmNetworkManagerまたはAlarmManagerが使用されます。

これらのAPIを使用すると、ジョブをスケジュールし、タスクを説明するサービスを実行できます。

UPDATEここで、新しいWorkManager(- docs )を使用する方が適切です。 Android-jobは間もなく廃止されます

12
nastasina

まず、JobServiceはサービスです。バックグラウンドサービスはあいまいです。バックグラウンドスレッドで実行されるサービスを意味すると思います。ジョブサービスはUIスレッドで実行されますが、その中に非同期タスクオブジェクトを作成してバックグラウンドで実行することができます。

あなたの質問から、JobServiceは進むべき道ではありません。

  1. そのクラスのonDestroyメソッドでIntentService(これはバックグラウンドスレッドで実行されます)を拡張するクラスを作成し、ブロードキャストを送信して、ブロードキャストにサービスを再起動させることができます。

     @onDestroy(){
     Intent broadcastIntent = new 
     Intent("com.example.myapp.serviceRestarted");
     sendBroadcast(broadcastIntent);}
    
  2. ブロードキャストレシーバーを拡張するクラスを作成する

     public class RestartServiceReceiver extends BroadcastReceiver {
     @Override
     public void onReceive(Context context, Intent intent) {
     context.startService(new Intent(context, 
     MyService.class));
    } 
    }
    
    1. マニフェストで、サービスと受信者を登録します
<receiver
            Android:name=".RestartServiceReceiver"
            Android:enabled="true"
            Android:exported="true">
            <intent-filter>
                <action Android:name="com.example.myapp.serviceRestarted" />
                <action Android:name="Android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

ブート許可とは、システムがブートを完了したときに受信者を呼び出せるようにすることです。受信者が呼び出されると、サービスが再度呼び出されます。

6
Idee

this および以下のコメント1の他のリンクによると

タスクにはAlarmManagerを使用する必要があります。

Doze中に起動するアラームを設定する必要がある場合は、次を使用します。

 setAndAllowWhileIdle() or setExactAndAllowWhileIdle().

バックグラウンドで作業を行うさまざまな方法の完全に理解しやすい説明については、以下をお読みください: https://www.bignerdranch.com/blog/choosing-the-right-background-scheduler-in-Android/

幸運を!

2
Mena

Androidの以前のバージョンでは、人々はこの目的のためにハンドラーまたはバックグラウンドサービスを使用していました。しばらくして、彼らは恒久的なスケジュールされた作品のアラームマネージャークラスを発表しました。

Whatsapp、facebook、または一部のソーシャルメディアアプリケーションは、ほとんどの場合、通知にGoogleクラウドメッセージングを使用しますが、これは役に立たないものです。

これにはアラームマネージャを使用することをお勧めします。 KitKatバージョン(4.2)以降、オペレーティングシステムは、バッテリーをより適切に使用するためにバックグラウンドハンドラーをブロックします。

バックグラウンドサービスは、主に画像のアップロードまたは終了時間のある重いプロセスに使用されます。 Whatsappで友人にビデオを送信すると、バックグラウンドプロセスが開始され、ビデオがバックエンドサーバーにアップロードされます。

古いバージョンのサポートをサポートするためのJobScheduler apiについてはわかりませんが、Alarm Managerと同じくらい良いです。

1

「START_STICKYでreturn start_stickyを使用すると、十分なメモリが確保された後にサービスを再作成し、nStartを指定してonStartCommand()を再度呼び出すようにOSに指示します。START_NOT_STICKYは、また、3番目のコードSTART_REDELIVER_INTENTであり、OSにサービスを再作成し、同じ意図をonStartCommand()に再配信するように指示します。

期間1分でタイマーを設定し、コードを実行します。

ユーザーが強制的に停止したときにサービスを再起動する場合も、「以前の回答として」実行できます

  1. そのクラスのonDestroyメソッドでIntentService(これはバックグラウンドスレッドで実行されます)を拡張するクラスを作成し、ブロードキャストを送信して、ブロードキャストにサービスを再起動させることができます。

    @onDestroy(){
        Intent broadcastIntent = new Intent("com.example.myapp.serviceRestarted");
        sendBroadcast(broadcastIntent);
    }
    
  2. ブロードキャストレシーバーを拡張するクラスを作成する

    public class RestartServiceReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            context.startService(new Intent(context, MyService.class));
        } 
    }
    
  3. マニフェストで、サービスとレシーバーを登録します

    <receiver
       Android:name=".RestartServiceReceiver"
        Android:enabled="true"
        Android:exported="true">
        <intent-filter>
            <action Android:name="com.example.myapp.serviceRestarted" />
            <action Android:name="Android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
    

また、AlarmManagerを使用できます。Dozeで起動するアラームを設定する必要がある場合は、次を使用します。

setAndAllowWhileIdle()またはsetExactAndAllowWhileIdle()。

「現在の時刻(秒+ 60秒)」に設定して、次の分に設定します。

コードを実行し、最後に、AlarmManagerを次の分リセットします。

また、「RECEIVE_BOOT_COMPLETED」の場合、brodcastRecieverを使用するだけで、デバイスの再起動後にサービスまたはAlarmManagerを開始できます

そして、この許可を入れます:

<uses-permission Android:name="Android.permission.RECEIVE_BOOT_COMPLETED" />
0
Momen Zaqout