Как стать автором
Обновить

Планирование задач в Android с использованием JobScheduler и IntentService

Время на прочтение 11 мин
Количество просмотров 37K
Всего голосов 3: ↑3 и ↓0 +3
Комментарии 10

Комментарии 10

jobFinished() непосредственно связан с задачами в отдельном потоке. Мне кажется, если в примере в статье выполнение выносится в отдельный поток, то в этой же статье надо рассказать и про jobFinished().
Если не сигнализировать о завершании, то повторные попытки выполнения задачи как раз будут идти с учетом BackoffCriteria
Все верно, я об этом и упомянул в конце статьи. С jobFinished я хочу показать возможности передачи информации между сервисами, а также варианты обработки ситуаций, когда нужно прекратить выполнение задачи, или когда нужно перезапланировать её выполнение и так далее.
Добавив всё это в текущую статью, я бы увеличил её размер в 2 раза.
На данный же момент, чтобы избежать повторов по BackoffCriteria можно вернуть false из метода onStopJob, и следующее выполнение будет обусловлено либо новой задачей либо запланированной повторяющейся.

Так onStopJob может и не вызваться никогда. Это же не признак завершения работы, а сигнал, что система хочет прервать работу.
Если в onStartJob вернуть true, и нигде не вызвать jobFinished, то система будет думать, что задача еще "крутиться", хотя по факту все уже давно могло закончиться.

В теории onStopJob действительно может не вызваться тогда, когда нечего останавливать, но в этом случае он и не несет никакого смысла.
На практике JobScheduler выделяет определенное время («окно») для каждой задачи, и если за это время задача все еще выполняется, то onStopJob для неё вызовется и будет иметь смысл.

Я полностью согласен с тем, что при выполнении задач в других потоках избегать вызова jobFinished — плохая практика, именно поэтому я об этом упомянул, но пример реализации не поместился в данную статью, так как для конкретного примера это не является чем-то значительным, что может сказаться на работе комплекса. Ведь все что делает задача — отправляет интент в IntentService на базе applicationContext, в котором и находится этот IntentService, таким образом у нас нет бесконечных циклов или утечек памяти. Единственный побочный эффект это то, что перестает держаться WakeLock, а тестовый IntentService вполне это переживет.

Тут нужно понимать, что вызов onStopJob не говорит, что сейчас вот все будет уничтожено и потеряно, основная его функция — сообщить об окончании удержания WakeLock. И если для целевой логики это действительно важно, то имеет смысл выполнить какие-то действия по информированию рабочего потока о том, что ему нужно экстренно завершать работу, а также очистить ресурсы для следующих задач.
Ну вот, кусок следующей статьи уже готов =))

Единственный вопрос про WakeLock.
Единственный побочный эффект это то, что перестает держаться WakeLock

Мне казалось, что как раз до тех пор пока мы не вызвем jobFinished WakeLock будет удерживаться, что в теории приведет к повышенному выжиранию батарейки. Или я не правильно понял мысль?
Да, действительно, это неоспоримая польза комментариев:)

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

С одной стороны да, вызвав jobFinished мы информируем о том, что нам WakeLock больше не нужен (но не факт что JobScheduler его сразу снимет, ведь он может быть нужен другой задаче), с другой стороны, если удержание WakeLock не уместно (например запланирован уход в Doze или еще что-нибудь подобное), то немедленно будет вызван onStopJob для всех задач и WakeLock будет отпущен.
Имхо стоит сразу описать использование JobIntentService — при условии, что хочется сохранить поведение в стиле IntentService — либо отрефакторить приложение, избавиться от IntentService целиком, переведя управление заданиями полностью на JobScheduler/JobService.
В противном случае нет ясности относительно jobFinished (в который ещё и JobParameters передать как-то надо).
Господа, перестал работать старый добрый DownloadManager под AndroidOreo-api 26 (не появляется Notification и DOWNLOAD_COMPLETE не срабатывает), возможно ли использование JobScheduler для такой задачи (фоновое скачивание mp3 файла большого размера)?
Если будете использовать JobScheduler придется самому предусматривать механизм прерывания и возобновления закачки, т.к. JobScheduler может как дать вам «рабочее» время и пространство, так и отобрать его.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории