Я хочу синхронизировать базу данных с данными сервера один раз в день, и где лучше всего поставить работу в очередь, чтобы она запускалась только один раз в день? WorkManager, похоже, не заботится о том, находится ли следующий вызов в очереди в RepeatInterval. Если я поставлю работу в очередь в класс приложения, и если эта работа будет завершена, WorkManager снова запустит ее, если я закрою и открою приложение.
Означает ли это, что я всегда должен проверять, поставлена ли работа в очередь перед вызовом WorkManager.enqueue()
?
val workInfo = workManager.getWorkInfosForUniqueWork("UNIQUE_WORK_NAME").get()?.getOrNull(0)
if (workInfo?.state == WorkInfo.State.ENQUEUED) {
// do nothing
return
}
workManager.enqueueUniquePeriodicWork(
"UNIQUE_WORK_NAME",
ExistingPeriodicWorkPolicy.KEEP,
PeriodicWorkRequestBuilder<SyncDbWorker>(
1,
TimeUnit.DAYS
)
.setConstraints(constraints)
.build())
Обновлено:
Одна вещь, которую я забыл упомянуть, это то, что внутри моего Worker я всегда возвращаюсь Result.success()
. Поэтому, если по какой-то причине работа не удалась, WorkManager повторит ее на следующей итерации.
@StavroXhardha дело в том, что это не относится ни к какой деятельности, эту работу просто нужно делать раз в день (запустил и забыл)
Вам не нужно проверять, поставлена ли работа уже в очередь, когда вы используете enqueueUniquePeriodicWork()
. Использование Keep
в качестве ExistingPeriodicWorkPolicy
гарантирует, что работа будет поставлена в очередь только в том случае, если нет другой работы с тем же uniqueWorkName
, которая уже запланирована.
Сказал, что обычное место, где вы можете поставить свою уникальную работу в очередь, — это обратный вызов onCreate()
в вашем приложении. Это гарантирует, что работа запланирована.
Имейте в виду, что PeriodicWorkRequest
может со временем проскальзывать, как описано в документация. Я описал это в говорить (около 24:25), который я представил в прошлом месяце с возможным обходным путем. Предполагается, что поддержка DailyWorkers появится в v2.1.x в одном из следующих альфа-релизов.
WorkManager.enqueueUniquePeriodicWork(), похоже, не работает таким образом. Иногда он игнорирует интервал, когда я убиваю и перезапускаю приложение, по крайней мере, на моих эмуляторах. Это ошибка?
Я только что нашел ответ на свою проблему: issuetracker.google.com/issues/129654588#comment2
На данный момент в WorkManager нет ничего нового для этого. WorkManager не поддерживает точное время, а задержки являются относительными. Чтобы иметь настоящего «ежедневного работника», мы должны также учитывать изменения в телефонном часовом поясе, а это не то, над чем мы работаем. Если вы считаете, что это важно иметь в библиотеке, отправьте запрос функции: issuetracker.google.com/issues/….
Что такое DailyWorkers??
Я использовал термин DailyWorker
, чтобы указать на Worker, который выполняется один раз в день всегда в одно и то же время (например, Worker, который выполняется каждый день в 6:00 утра).
@pfmaggi Разве AlarmManager не подходит для чего-то, что нужно выполнить в определенное время, например ExactTasks? Нельзя ли использовать AlarmManager с InexactRepeating
вместо DailyWorkers?
Если вам нужно выполнить в определенное время (например, 6 утра), AlarmManager — это единственный API на устройстве, доступный в это время. Лично я считаю, что FCM с сервера может быть лучшим вариантом в этом случае (но тогда это зависит от того, можно ли выполнить вашу задачу без подключения, в этом случае FCM может быть не лучшим вариантом). Если вам не нужно точное время, WorkManager — лучший вариант, поскольку он охватывает множество крайних случаев и обходных путей, таких как изменение расписания рабочих после принудительной остановки вашего приложения при первом запуске пользователя. Вам нужно будет повторно реализовать много WorkManager, чтобы получить аналогичные возможности.
Зависит от варианта использования, но если у вас есть приложение с одним действием, используйте его там, иначе . используйте его только в той деятельности, которая вам нужна.