以下のコードを使用して、Androids JobSchedulerAPIを使用してジョブを作成およびスケジュールしています。
Log.d("hanif", "Scheduling periodic job 2 hrs with 20 mins backoff linear");
JobInfo jobInfo = new JobInfo.Builder(JOB_ID,
new ComponentName(getApplicationContext(), MyJobService.class))
.setPeriodic(TimeUnit.HOURS.toMillis(2))
.setRequiresCharging(true)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setBackoffCriteria(TimeUnit.MINUTES.toMillis(20),
JobInfo.BACKOFF_POLICY_LINEAR)
.build();
JobScheduler scheduler =
(JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
scheduler.schedule(jobInfo);
つまり2時間ごとに実行される定期的なジョブと、ジョブが失敗した場合に20分*の数値を実行する線形バックオフポリシーは失敗します。
私のジョブサービスコードは次のように書かれています。
public class MyJobService extends JobService {
@Override
public boolean onStartJob(JobParameters jobParameters) {
Log.d("hanif", "onStartJob");
new MyWorker(getApplicationContext(), this, jobParameters).execute();
return true;
}
@Override
public boolean onStopJob(JobParameters jobParameters) {
Log.d("hanif", "onStopJob");
return true;
}
private static class MyWorker extends AsyncTask<Void, Void, Boolean> {
private final Context mContext;
private final MyJobService mJobService;
private final JobParameters mJobParams;
public MyWorker(Context context, MyJobService myJobService, JobParameters jobParameters) {
mContext = context;
mJobService = myJobService;
mJobParams = jobParameters;
}
@Override
protected Boolean doInBackground(Void... voids) {
Log.d("hanif", "Work start!");
for (int i=0; i<999999999; i++) {}
int counter = Prefs.getCounter(mContext);
Log.d("hanif", "Work done! counter: " + counter);
if (counter == 3) {
Log.d("hanif", "DO RESCHEDULE");
Prefs.resetCounter(mContext);
return true;
}
Log.d("hanif", "DO NOT RESCHEDULE");
Prefs.increaseCounter(mContext);
return false;
}
@Override
public void onPostExecute(Boolean reschedule) {
if (reschedule) {
mJobService.jobFinished(mJobParams, true);
} else {
mJobService.jobFinished(mJobParams, false);
}
Log.d("hanif", "------------------------------------------");
}
}
}
そして最後に、ログ出力は次のようになります。
03-27 12:57:11.677 7383 7383 D hanif : Scheduling periodic job 2 hrs with 20 mins backoff linear
03-27 12:57:31.904 7383 7383 D hanif : onStartJob
03-27 12:57:31.909 7383 8623 D hanif : Work start!
03-27 12:57:42.110 7383 8623 D hanif : Work done! counter: 0
03-27 12:57:42.111 7383 8623 D hanif : DO NOT RESCHEDULE
03-27 12:57:42.125 7383 7383 D hanif : ------------------------
03-27 14:58:50.786 7383 7383 D hanif : onStartJob
03-27 14:58:50.789 7383 21490 D hanif : Work start!
03-27 14:59:00.952 7383 21490 D hanif : Work done! counter: 1
03-27 14:59:00.953 7383 21490 D hanif : DO NOT RESCHEDULE
03-27 14:59:00.962 7383 7383 D hanif : ------------------------
03-27 16:57:12.021 7383 7383 D hanif : onStartJob
03-27 16:57:12.045 7383 32028 D hanif : Work start!
03-27 16:57:22.229 7383 32028 D hanif : Work done! counter: 2
03-27 16:57:22.230 7383 32028 D hanif : DO NOT RESCHEDULE
03-27 16:57:22.238 7383 7383 D hanif : ------------------------
03-27 18:57:11.984 7383 7383 D hanif : onStartJob
03-27 18:57:11.989 7383 13217 D hanif : Work start!
03-27 18:57:22.123 7383 13217 D hanif : Work done! counter: 3
03-27 18:57:22.124 7383 13217 D hanif : DO RESCHEDULE
03-27 18:57:22.130 7383 7383 D hanif : ------------------------
03-27 19:20:57.468 7383 7383 D hanif : onStartJob
03-27 19:20:57.482 7383 1913 D hanif : Work start!
03-27 19:21:07.723 7383 1913 D hanif : Work done! counter: 0
03-27 19:21:07.724 7383 1913 D hanif : DO NOT RESCHEDULE
03-27 19:21:07.733 7383 7383 D hanif : ------------------------
03-27 19:21:57.669 7383 7383 D hanif : onStartJob <--- Why is this called again?
03-27 19:21:57.675 7383 3025 D hanif : Work start!
03-27 19:22:07.895 7383 3025 D hanif : Work done! counter: 1
03-27 19:22:07.896 7383 3025 D hanif : DO NOT RESCHEDULE
03-27 19:22:07.906 7383 7383 D hanif : ------------------------
03-27 21:40:53.419 7383 7383 D hanif : onStartJob
03-27 21:40:53.423 7383 31526 D hanif : Work start!
03-27 21:41:03.857 7383 31526 D hanif : Work done! counter: 2
03-27 21:41:03.858 7383 31526 D hanif : DO NOT RESCHEDULE
03-27 21:41:03.867 7383 7383 D hanif : ------------------------
OnStartJobが2回呼び出されるのはなぜですか?
多くの欲求不満の後、私はこの問題の原因を突き止めました。
not定期的なジョブでjobFinished(JobParameters, true)
を呼び出す必要があります。 true
にneedsReschedule
を渡すと、ジョブがキューに複製されます(元のジョブが上書きされることが予想されますが、そうではないようです)。タスクが失敗した場合でも、常にjobFinished(JobParameters, false)
を使用する必要があります。
これが誤ったAPIの使用としてカウントされるのか、Androidバグ)としてカウントされるのかについては、お任せします。
JobSchedulerはAndroid Oreoでより多く使用されるため、例でいくつかの問題を説明したいと思います。
onStopJob()
オーバーライドされたメソッドは、true
のみを返します。処理中にジョブが中断された場合、つまり充電器が接続されていないか、JobInfoで設定されているネットワークがない場合は、この関数を使用してタスク/ジョブをすぐにキャンセルする必要があります。次に、ジョブを再スケジュールする必要があることを示すtrue
を返す必要があります。
MyJobService
には、private
タスクへのMyWorker
参照が必要です。 onStartJob()
はそれを設定します。 onStopJob()
はこれを使用して、タスクをすぐにキャンセルします。
jobFinished()
メソッド内のtrue
にneedsReschedule
を渡すことは、特にタスク内で呼び出される場合、通常は必要ありません。ジョブが中断された場合、onStopJob()が呼び出されてジョブがキャンセルされ、trueを返すとジョブが再スケジュールされます。私は1つの例しか見たことがありません ここ ここでneedsReschedule
はtrue
に設定されています。これはonStartJob()
内にあり、前提条件のダブルチェックが満たされない場合は、true
の代わりにjobFinished(args, true)
を実行してからreturn false
を実行します。
お役に立てれば!