我正在使用以下代码使用 Androids JobScheduler API 创建和安排作业:
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 min * number 的线性退避策略会在作业失败的情况下失败。
我的工作服务代码如下所示:
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 被调用两次?