Ответ 1
- Запланируйте работу, которая выполняется один раз в день в фоновом режиме
Вы можете запланировать PeriodicWorkRequest
для этого, который должен быть поставлен в очередь с enqueueUniquePeriodicWork
. Это гарантирует, что одновременно может быть активен только один PeriodicWorkRequest
с определенным именем.
Constraints constraint = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();
PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(MyWorker.class, 1, TimeUnit.DAYS)
.setConstraints(constraint)
.build();
WorkManager workManager = WorkManager.getInstance();
workManager.enqueueUniquePeriodicWork("my_unique_worker", ExistingPeriodicWorkPolicy.KEEP, workRequest);
- Задача состоит в том, чтобы выполнить выборку данных из REST API (и, если возможно, опубликовать их в объекте LiveData).
Это можно сделать, отправив ваш запрос синхронно в пределах doWork()
вашего работника. Я бы не использовал LiveData
в вашем классе Worker
. Мы подойдем к этому позже. Вызов API будет выглядеть с Retrofit, например, так:
@Override
public WorkerResult doWork() {
Call<MyData> call = APILayer.getInstance().fetchData();
Response<MyData> response = call.execute();
if (response.code() == 200) {
MyData data = response.body();
// ...
} else {
return Result.RETRY;
}
// ...
return Result.SUCCESS;
}
- Когда данные вернутся, убедитесь, что они новее локальных данных.
Вы получили данные API синхронно. Синхронно извлекайте локальные данные и делайте все, что вам нужно, чтобы сравнить их.
- Уведомить пользователя о наличии новых данных.
Если вы запланируете задачу с помощью WorkManager
, она гарантированно запустится, даже если ваше приложение принудительно завершается или устройство перезагружается. Таким образом, ваша задача может быть выполнена, пока ваше приложение не запущено. Если вы хотите уведомить пользователя в любом случае, вы можете отправить уведомление. Если вы хотите уведомить пользователя на определенном экране, вы можете подписаться на статус ваших задач. Например, вот так (взято из официального руководства):
WorkManager.getInstance().getStatusById(compressionWork.getId())
.observe(lifecycleOwner, workStatus -> {
// Do something with the status
if (workStatus != null && workStatus.getState().isFinished()) {
// ...
}
});
Там также getStatusesForUniqueWork(String uniqueWorkName)
для нашего примера.
В официальном руководстве также объясняется, как вернуть данные от вас Задача, с помощью которой вы можете позвонить, например, setValue()
на ваш MutableLiveData
.
Я бы предложил обновить ваши локальные данные в вашем Worker
, подписаться на статус вашего работника и, как только он преуспеет, обновить ваш пользовательский интерфейс с локальными данными (если вы все равно не подписаны на свои локальные данные, то есть с Room и LiveData
),
Изменить: В отношении пункта 4, состояние чтения периодических рабочих запросов работает немного иначе. Они переключаются только между ENQUEUED
и RUNNING
до CANCELLED
. Но никогда не будет состояния SUCCEEDED
или FAILED
. Поэтому прослушивание isFinished()
может оказаться не тем, что вы ожидаете.