Android JobScheduler выполняется несколько раз

Я использую приведенный ниже код для создания и планирования задания с использованием 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 мин. * Номер, терпит неудачу в случае сбоя задания.

Код моей службы работы написан следующим образом:

 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 называется два раза?

После многих разочарований я понял, что вызывает эту проблему.

Вы не должны называть jobFinished(JobParameters, true) периодическим заданием. Передача true для needsReschedule заставит задание дублироваться в очереди (вы ожидали бы, что оно будет перезаписано исходным, но, похоже, это не так). Вы всегда должны использовать jobFinished(JobParameters, false) , даже если ваша задача не выполняется.

Что касается того, считается ли это неправильным использованием API или ошибкой Android, я оставлю это до вас.

Поскольку JobScheduler будет использоваться намного больше с Android O, я хотел бы описать несколько проблем с примером:

Метод onStopJob() возвращает true . Если ваша работа прерывается во время обработки, т.е. зарядное устройство отключено или нет сети, установленной в JobInfo, эту функцию следует использовать, чтобы сразу же отменить задачу / задание. Затем он должен вернуть true указывая, что работа должна быть перенесена.

MyJobService должен иметь private ссылку на задачу MyWorker . onStartJob() устанавливает его. onStopJob() использует его, чтобы немедленно отменить задачу.

Передача true для needsReschedule в jobFinished() обычно не требуется, особенно при вызове в вашей задаче. Если задание прерывается, onStopJob () будет вызываться для его отмены, а возврат истины изменит его. Я видел только один пример здесь, где needsReschedule имеет значение true . Он находится внутри onStartJob() и если двойная проверка предварительных условий не выполняется, jobFinished(args, true) а затем return false вместо true .

Надеюсь это поможет!

Intereting Posts
Использовать широковещательный приемник для улавливания входящего вызова, onReceive не срабатывает? Растровое изображение с закругленными углами с инсультом Android ContactsContract и создание нескольких версий SDK Реагируйте собственный пользовательский вид, нет propType для встроенного носителя Android Push Notification (GCM), есть ли ежедневный лимит? Android NullPointerException в Instrumentation.execStartActivity Есть ли лучший способ отладки OpenGL, чем вызов glGetError после каждой команды? Включение и выключение экрана в программном обеспечении Android Ориентация изображения от цели галереи / камеры Android намерен передавать текстовые / простые данные на Google Диск Обнаружите движение человека и определите его части тела, движущиеся в направлении камеры на Android Выбрать + скопировать текст в TextView? Каков наилучший способ сделать скользящие изображения в кардвале внутри recycler? Логотип ActionBar с центром и элементами действия по сторонам Почему WebView не может открыть некоторые локальные URL (Android)?