JobScheduler выдает проблемы с Android

Планировщик заданий запускается каждые 10 минут периодически. Что мне нужно сделать, чтобы запустить расписание, как только приложение запустится и будет периодически запускаться каждые 10 минут. Теперь происходит следующее: после установки приложения для запуска расписания требуется 10 минут. Как заставить его запускаться сначала, а затем повторяться каждые 10 минут? У меня есть код для обновления данных на сервере в onStartJob(). Но время загрузки тоже от 7 до 25 минут. Я хочу загружать данные каждые 10 минут, но они меняются случайным образом. Почему это?

JobInfo jobInfo =
    new JobInfo.Builder(MYJOBID, jobService).setPeriodic(600000).
    setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY).
    setRequiresCharging(false).
    setRequiresDeviceIdle(false).
    setPersisted(true).
    setExtras(bundle).
    build();

int jobId = jobScheduler.schedule(jobInfo);
if(jobScheduler.schedule(jobInfo)>0){
    Toast.makeText(LiveTrack.this,
            "Successfully scheduled job: " + jobId,
            Toast.LENGTH_SHORT).show();
}else{
    Toast.makeText(LiveTrack.this,
            "RESULT_FAILURE: " + jobId,
            Toast.LENGTH_SHORT).show();
}

.

public class MyJobService extends JobService {

    @Override
    public boolean onStartJob(JobParameters jobParameters) {
        new MyDownloadTask().execute();
        return false;
    }
}

person Amrita Stha    schedule 19.09.2017    source источник


Ответы (1)


Я хочу загружать данные каждые 10 минут, но они меняются случайным образом. Почему это?

JobScheduler API не обещает повторения через определенные промежутки времени.

Но время загрузки тоже от 7 до 25 минут.

Согласно setPeriodic() ссылке:

Вы не можете контролировать, когда в течение этого интервала это задание будет выполнено, только гарантия того, что оно будет выполнено не более одного раза в течение этого интервала.

Тем не менее, мы должны получать обратный вызов с интервалом не более 20 минут. Давайте посмотрим на JobInfo.Builder исходный код. Начиная с setPeriodic(long):

 public Builder setPeriodic(long intervalMillis) {
        return setPeriodic(intervalMillis, intervalMillis);
 }

Хорошо, это называет его перегруженным двоюродным братом. Что говорит:

Укажите, что это задание должно повторяться с заданным интервалом и гибкостью. Задание может выполняться в любое время в окне гибкой длины в конце периода.

Вау, значит, в нашем случае продолжительность flex тоже 10 минут? Не так быстро:

/**
  * Specify that this job should recur with the provided interval and flex. The job can
  * execute at any time in a window of flex length at the end of the period.
  * @param intervalMillis Millisecond interval for which this job will repeat. A minimum
  *                       value of {@link #getMinPeriodMillis()} is enforced.
  * @param flexMillis Millisecond flex for this job. Flex is clamped to be at least
  *                   {@link #getMinFlexMillis()} or 5 percent of the period, whichever is
  *                   higher.
  */

Применяется минимальное значение getMinPeriodMillis().

:|

Какой минимальный срок вы спрашиваете?

MIN_PERIOD_MILLIS = 15 * 60 * 1000L; // 15 minutes

Таким образом, ваш вызов setPeriodic(60000) ничего не дает. Минимальный период остается зажатым до 15 минут.

JobScheduler на самом деле не предназначен для точного повторения периодов. На самом деле он был создан потому, что большинство приложений злоупотребляли AlarmManger API, который обеспечивает эту (точно повторяющуюся) функциональность.

person iceman    schedule 19.09.2017
comment
привет .. спасибо за ответ. В методе onStop() есть оператор return false. Если я устанавливаю его в true, он не работает (т.е. данные не обновляются на сервере). Почему это? - person Amrita Stha; 19.09.2017
comment
@AmritaStha Спасибо, что приняли. Я думаю, вы имеете в виду onStopJob(). Если вы прочитаете javadoc, вы увидите, что когда onStopJob() вызывается, когда ваш onStartJob(), скорее всего, выйдет из строя. Возврат из onStopJob() — это просто указание системе повторить попытку или нет. Я думаю это отдельный вопрос сам по себе. Я предлагаю вам задать другой вопрос для этого с деталями. - person iceman; 19.09.2017
comment
Извините, что это было для onStartJob()... Если возвращается true, код внутри него не работает. - person Amrita Stha; 19.09.2017
comment
@AmritaStha См. meta.stackexchange.com/questions/39223/. Подробнее, код поможет. Новый вопрос будет более заметным, и другие люди смогут дать более точные ответы. - person iceman; 19.09.2017
comment
А также, пожалуйста, проголосуйте, если вы найдете этот ответ правильным и полезным :) - person iceman; 19.09.2017