Android Worker выполняет задание несколько раз

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

WorkManager workManager = WorkManager.getInstance();
PeriodicWorkRequest ulpBackup;

ulpBackup = new PeriodicWorkRequest
    .Builder(Ulp.class, 15, TimeUnit.MINUTES)
    .addTag(activity.getString(R.string.job_tag))
    .build();
workManager.enqueue(ulpBackup);

А вот и UlpBackup.class

public class UlpBackup extends Worker {
    private Integer responseCounter = 0;

    public UlpBackup() {}

    @NonNull
    @Override
    public Result doWork() {

        Log.d(logTag, "Starting periodic backup job";   
        final CountDownLatch countDownLatch = new CountDownLatch(1);

        /** Read from local database and upload to firestore **/

        localdb.setAPIListener(new APIListener() {
            @Override
            public void OnSuccess() {
                responseCounter++;
                if (responseCounter == 5) {
                    countDownLatch.countDown();
                }
            }

            @Override
            public void OnFailure() {
                responseCounter++;
                if (responseCounter == 5) {
                    countDownLatch.countDown();
                }
            }
        });

        localdb.sync();

        try {
            countDownLatch.await(300, TimeUnit.SECONDS);
        } catch (Exception exception) {
            Log.e(logTag, "Error in user list backup job " + exception.getMessage());
            return Result.FAILURE;
        }

        Log.e(logTag, "Ulp backup completed");
        return Result.SUCCESS;
}

Приведенный выше код работает нормально, и работа выполняется примерно каждые 15 минут, как и ожидалось. Единственное, чего я не понимаю, это то, что каждый раз, когда задание выполняется несколько раз, может ли кто-нибудь объяснить, почему и как я могу этого избежать?

Из журнала:

09-15 23:33:37.514 8190-8410: Starting periodic backup job
09-15 23:33:37.520 8190-8414: Starting periodic backup job
09-15 23:33:37.561 8190-8412: Starting periodic backup job
09-15 23:33:37.568 8190-8413: Starting periodic backup job
...
...
09-15 23:33:38.183 8190-8414: Ulp backup completed
09-15 23:33:39.164 8190-8412: Ulp backup completed
09-15 23:33:39.580 8190-8413: Ulp backup completed
09-15 23:38:37.517 8190-8410: Ulp backup completed

person spiderloop    schedule 16.09.2018    source источник
comment
Это также происходит после новой установки вашего приложения? Может быть, вы ставили задание в очередь несколько раз ...   -  person HedeH    schedule 16.09.2018
comment
@HedeH вы правы, вроде как свежая установка, приложения работают. Похоже, проблема в том, что я продолжаю перезагружать приложение, которое запускается в очереди каждый раз, когда я его перезагружаю. Я добавляю логику защиты, как показано здесь, чтобы избежать такой проблемы stackoverflow.com/questions/51612274/ Спасибо за помощь!   -  person spiderloop    schedule 16.09.2018
comment
Пожалуйста :)   -  person HedeH    schedule 17.09.2018


Ответы (2)


Вы можете использовать следующий метод: enqueueUniquePeriodicWork() и реализовать его так:

WorkManager.getInstance().enqueueUniquePeriodicWork("YOUR_TAG", ExistingPeriodicWorkPolicy.KEEP, workRequest);

Обратите внимание, что второй параметр является ключевым. Перечисление может быть KEEP или REPLACE.

person StevenTB    schedule 04.04.2019

Я думаю, что опаздываю с ответом на этот вопрос, и вы, возможно, тоже его поправили ... Но я все равно пытаюсь помочь ...

Единственное, чего я не понимаю, это то, что каждый раз, когда задание выполняется несколько раз, can someone explain почему и как я могу этого избежать?

Объяснение :

Все будут шокированы, если я скажу:

  1. Googles android не контролирует крор процессов, выполняемых в режиме реального времени.
  2. Ему даже не хватает понимания даже сказать, что процесс xyz завершен? или работает? или закончили?
  3. Это оно. И результат - это ваша проблема

Боже мой .. Это приведет к data-loss, если я буду выполнять какие-либо операции с базой данных, то .. !! ??

Да, это приводит к многократной потере данных ..

Есть ли тут у андроида и у разработчиков какие-то обходные пути ...?

Да, предпочитаю использовать IntentService.

Что такого особенного в IntentService?

Если intentservice уже запущен и даже если thousands раз он вызывается ... Тогда и в этом случае ... все вызовы хранятся в queue андроидом и обрабатываются one by one и one after another, а после того, как один будет finished, тогда только другой ждет awakes и начинает выполнять это

Надеюсь, поможет.

person sandhya sasane    schedule 19.09.2018
comment
startService больше не будет работать на устройствах с Android 8.0 с 1 ноября, поэтому я не рекомендую это делать. Для того, кто задает вопрос, обратитесь к этому вопросу https://stackoverflow.com/questions/50435131/android-workmanager-periodicworkrequest-is-not-unique - person Josh; 20.09.2018