Android WorkManager API для запуска ежедневных задач в фоновом режиме - PullRequest
0 голосов
/ 18 мая 2018

Мне нужно вызывать один API ежедневно в фоновом режиме, даже если приложение закрыто.Я видел про WorkManager API.Для моего сценария я попробовал PeriodicWorkRequest, но, к сожалению, он не работает, как мой ожидаемый результат.Я использовал этот код в классе Application

 PeriodicWorkRequest.Builder myWorkBuilder =
                new PeriodicWorkRequest.Builder(MyWorker.class, 24,
                        TimeUnit.HOURS);

        PeriodicWorkRequest myWork = myWorkBuilder.build();
        WorkManager.getInstance().enqueue(myWork);

Но он запускается повторно 11 раз, когда приложение открывается впервые после этого, оно не запускается через 24 часа.Пожалуйста, кто-нибудь, помогите мне решить.

Ответы [ 6 ]

0 голосов
/ 02 июля 2018

Использовать версию WorkManager 1.0.0-alpha04 .Вы можете просмотреть примечания к выпуску здесь

Также обратитесь к этой демонстрационной версии PeriodicWorkRequest GitHub , которая обновляет счетчик дней один раз в день (каждые 24 часа) в течение периода обслуживания.Он выполняет метод doWork (), независимо от того, открыто приложение или закрыто.

WorkManager все еще находится в альфа-режиме, поэтому он будет работать полностью для всех устройств после выпуска окончательной версии.

0 голосов
/ 28 июня 2018

Если вы хотите, чтобы ваш PeriodicWorkRequest не создавался несколько раз, вы можете использовать метод WorkManager.enqueueUniquePeriodicWork для планирования вашего работника:

Этот метод позволяет вампоставить в очередь уникальное имя PeriodicWorkRequest, где одновременно может быть активен только один PeriodicWorkRequest с определенным именем.Например, вы можете захотеть, чтобы была активна только одна операция синхронизации.Если имеется одно ожидание, вы можете разрешить его запуск или заменить его новой работой.


Например:

PeriodicWorkRequest.Builder myWorkBuilder =
            new PeriodicWorkRequest.Builder(MyWorker.class, 24, TimeUnit.HOURS);

PeriodicWorkRequest myWork = myWorkBuilder.build();
WorkManager.getInstance()
    .enqueueUniquePeriodicWork("jobTag", ExistingPeriodicWorkPolicy.KEEP, myWork);
0 голосов
/ 27 июня 2018

Начиная с alpha03 вы можете запланировать уникальную периодическую работу: https://developer.android.com/jetpack/docs/release-notes

WorkManager.enqueueUniquePeriodicWork (String uniqueWorkName, ExistingPeriodicWorkPolicy существующийPeriodicWorkPolicy, PeriodicWorkRequest periodWorkWorkue уникальная периодическая работаWorkue 100 позволяет выполнять уникальные периодические операции.*

Так что сейчас добиться того, чего вы хотите, гораздо проще.

0 голосов
/ 03 июня 2018

В альфа 01 возникла проблема, из-за которой:

Исправлена ​​ошибка, из-за которой рабочие переносились в Application.onCreate ().

Используйте последнюю версию WorkManager, то есть 1.0.0-alpha02.Проверьте примечания к выпуску для получения дополнительной информации

0 голосов
/ 24 мая 2018

Если вы добавите тег к PeriodicWorkRequestBuilder, а затем вызовете WorkManager.getInstance().cancelAllWorkByTag(REQUEST_TAG) перед постановкой в ​​очередь периодического запроса, это предотвратит возникновение дубликатов:

Android Workmanager PeriodicWorkRequest не является уникальным

0 голосов
/ 21 мая 2018

Я думаю, что есть три проблемы.

1) Вы создаете новую периодическую работу каждый раз, когда вы enqueue myWork в WorkManager Экземпляре.

Попробуйтелогика в методе doWork() вашего MyWorker.class запускается один раз в первый раз, выполняется дважды во второй раз.Скорее всего, вы добавили 11 работ в Диспетчер работ, и поэтому он запускался 11 раз, когда вы последний раз проверяли.Если вы создаете новые работы и добавляете их в диспетчер работ, то увеличивается число прогонов myWork.

Подобно планировщику заданий, вы должны проверить, существует ли задание, прежде чем добавлять его вДиспетчер работ.

Пример кода:

final WorkManager workManager = WorkManager.getInstance();
final LiveData<List<WorkStatus>> statusesByTag = workManager
        .getStatusesByTag(TAG_PERIODIC_WORK_REQUEST);

    statusesByTag.observe(this, workStatuses -> {
    if (workStatuses == null || workStatuses.size() == 0) {
        Log.d(TAG, "Queuing the Periodic Work");
        // Create a periodic request
        final PeriodicWorkRequest periodicWorkRequest =
                new PeriodicWorkRequest.Builder(SyncWorker.class, 30, TimeUnit.MINUTES)
                        .addTag(TAG_PERIODIC_WORK_REQUEST)
                        .build();

        // Queue the work
        workManager.enqueue(periodicWorkRequest);
    } else {
        Log.d(TAG, "Work Status Size: " + workStatuses.size());
        for (int i = 0; i < workStatuses.size(); i++) {
            Log.d(TAG, "Work Status Id: " + workStatuses.get(i).getId());
            Log.d(TAG, "Work Status State: " + workStatuses.get(i).getState());
        }
        Log.d(TAG, "Periodic Work already exists");
    }
});

В приведенном выше примере я использую уникальный тег TAG_PERIODIC_WORK_REQUEST, чтобы идентифицировать свою периодическую работу и проверять, существует ли она или нет перед созданиемit.

2) Ваша работа может не работать, когда приложение убито.

Какой бренд вы тестируете?Это Xiaomi?Вы тестировали его на нескольких других брендах и получили тот же результат?

Был ли он в режиме Doze?И как вы проверяете, что работа не выполняется, если вы установили 24-часовое время?

Диспетчер работ обеспечивает обратную совместимость, но все же вам необходимо обрабатывать логику, специфичную для устройства.На устройствах Xiaomi, аналогично Job Scheduler (или Firebase Job Dispatcher или Alarm), периодическая работа останавливается, когда приложение закрывается.

3) Я просто думаю, что PeriodicWorkRequest, предоставленный WorkManager, глючит.

Я тестировал его с начала предыдущей недели на нескольких устройствах.Я создал работу, когда приложение было запущено в первый раз, и не открывал его три дня.Он запускался один раз в первый раз, два раза, когда была запущена вторая синхронизация, и между ними он увеличился в 13 раз, упал до 1 раза, 4 раза и т. Д.,

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

final PeriodicWorkRequest periodicWorkRequest =
            new PeriodicWorkRequest.Builder(SyncWorker.class, 30, TimeUnit.MINUTES)
                    .addTag("periodic-work-request")
                    .build();

// Queue the work
WorkManager.getInstance().enqueue(periodicWorkRequest);

Я понимаю, что, поскольку оно все еще находится в альфа-версии.Я не думаю, что вы должны использовать его в производстве.

...