Проблема с андроидами «OneTimeWorker», он запускается при запуске приложения

#java #android #worker

Вопрос:

Краткое описание:


В настоящее время я работаю в Android Studio с OneTimeWorkRequest() . Чего я хочу добиться, так это создать фонового рабочего, который запускается и повторяется «почти» в определенное время, например, каждый час (09:00, 10:00 и т. Д.). Это не должно быть точно, но не должно слишком сильно изменяться после длительного времени работы.

Я уже знаю, что рабочий запускается как минимум каждые 15 минут из-за ограничений Android (например, механизм экономии заряда батареи и так далее). Мне не нужно, чтобы работник работал точно в заданное время, но, по крайней мере, почти в заданное время! Вот почему я использовал OneTimeWorkRequest() вместо PeriodicWorkRequest() этого, потому что мне нужна была возможность изменения настройки интервала для рабочего, поскольку в документации упоминается, что PeriodicWorkRequest() это приведет к временной задержке от одного выполнения к другому.

Что я сделал:


Я создал пользовательский рабочий класс и использовал OneTimeWorkRequest() его в своем MainActivity для создания BackgroundWorker. Я установил время setInitialDelay() работы рабочего на 20 минут для целей тестирования. Каждый раз, когда работник делал doWork() это, он создает еще OneTimeWorkRequest() одного в конце выполнения, поэтому в данный момент времени создается цепочка работников. Работник встает в очередь с enqueueUniqueWork() помощью метода из WorkerManager.getInstance(context) , и вычисляется интервал.

Проблема:


Каждый раз, когда я закрываю процесс приложения и снова открываю приложение, работник выполняется напрямую. Также, когда я перечисляю всех работников, созданных указанным тегом, в нем перечисляется много работников. Мне кажется, что моя логика создала слишком много рабочих, не закрыв старых, или она создает несколько? Все же я думал enqueueUniqueWork() , что он заменит или создаст только уникального/единственного работника с данным тегом… Кроме того WorkManager.getInstance(this).cancelAllWorkByTag(TAG) , функция не закрывает (далее в этом посте) перечисленного работника!

Прямо сейчас для меня важно не то, как создать выполнение рабочего в данный момент времени, а как создать согласованную рабочую цепочку, при OneTimeWorkRequest() этом не создавайте «перегрузку рабочего», если это возможно. И все же я открыт для альтернативных решений.

Итак, еще раз:

  • Почему рабочий выполняется после закрытия процесса и открытия приложения?
  • Почему в списке так много работников?
  • Создает ли моя логика одну единственную рабочую цепочку или несколько?
  • Является ли моя логика вообще последовательной/применимой таким образом?
  • Почему рабочий не закрывает использование .cancelAllWorkByTag(TAG) ?

Код:


// MainActivity.java:

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    ...
    
        // For testing purpose used...
    ListScheduledWorker(TAG);
    WorkManager.getInstance(this).cancelAllWorkByTag(TAG);
    ListScheduledWorker(TAG);
        // ...until here.

    CreateOneTimeWorker();
    
    ...
}

private void CreateOneTimeWorker(){
    long timeValue = 20;
    TimeUnit timeUnit = TimeUnit.MINUTES;
    String workerTag = MhdExpirationPushNotification.class.getSimpleName();
    OneTimeWorkRequest worker = new OneTimeWorkRequest.Builder(CustomPeriodicallyWorker.class)
            .setInitialDelay(timeValue, timeUnit)
            .addTag(workerTag)
            .setConstraints(Constraints.NONE)
            .build();
    WorkManager.getInstance(this).enqueueUniqueWork(workerTag, ExistingWorkPolicy.KEEP, worker);
}
 

// CustomPeriodicallyWorker.java:

 public Result doWork(){
    Log.v(TAG, "Work is in progress");
    try {
        CustomDateFormatter currentDateTime = new CustomDateFormatter();
        CustomDateFormatter targetDateTime = new CustomDateFormatter();
        targetDateTime.AddMinutes(20);
        long timeDifference = targetDateTime.GetDateTime().getTime() - currentDateTime.GetDateTime().getTime();

        OneTimeWorkRequest worker = new OneTimeWorkRequest.Builder(CustomPeriodicallyWorker.class)
                .setInitialDelay(timeDifference, TimeUnit.MILLISECONDS)
                .addTag(TAG)
                .build();
        WorkManager.getInstance(context).enqueueUniqueWork(TAG, ExistingWorkPolicy.REPLACE, worker);

    } catch (Exception e) {
        e.printStackTrace();
    }
    Log.v(TAG, "Work finished");;

    return Result.success();
}
 

// The function in MainActivity.java that lists all scheduled worker:

 private boolean ListScheduledWorker(String tag) {
    WorkManager instance = WorkManager.getInstance(this);
    ListenableFuture<List<WorkInfo>> statuses = instance.getWorkInfosByTag(tag);
    try {
        boolean running = false;
        List<WorkInfo> workInfoList = statuses.get();
        for (WorkInfo workInfo : workInfoList) {
            Log.i(TAG, "Scheduled Worker running with ID: "   workInfo.getId());
            WorkInfo.State state = workInfo.getState();
            running = state == WorkInfo.State.RUNNING | state == WorkInfo.State.ENQUEUED;
        }
        return running;
    } catch (ExecutionException e) {
        e.printStackTrace();
        return false;
    } catch (InterruptedException e) {
        e.printStackTrace();
        return false;
    }
}
 

// The ListScheduledWorker(String tag) prints me this out:

 I/TAG: Scheduled Worker running with ID: 27bb31ed-5984-434f-a6ca-08b50462b3df
    Scheduled Worker running with ID: 2d6abbb1-3a55-4652-83ca-60617631e0ab
    Scheduled Worker running with ID: 3e89851d-7e0b-410d-86b8-e664a4d710f0
    Scheduled Worker running with ID: 430e77b2-5fb8-4596-acd5-51e35a6a538b
    Scheduled Worker running with ID: 73b57443-8195-4c55-a24d-bd643b88e13c
    Scheduled Worker running with ID: 74c8a44b-2a9a-4448-b3d5-e2c085be3d06
    Scheduled Worker running with ID: 75deabd3-08e8-403a-b9d7-6c23f114a908
    Scheduled Worker running with ID: 89ec6239-e215-4ea1-a7bc-fcaa8b63065c
    Scheduled Worker running with ID: 9363038e-be74-4a83-9d1f-eeeda35ebbfa
    Scheduled Worker running with ID: 9a09806f-f0cf-43c1-a4f6-1f10448904f4
    Scheduled Worker running with ID: c6686c56-fd8a-4866-8eb1-5124654b6cb7
    Scheduled Worker running with ID: d3343328-db8f-4c8d-8055-a1acfc9d1c5c
    Scheduled Worker running with ID: dea9272f-6770-45f0-ba66-2c845e156d7b
    Scheduled Worker running with ID: eb4c111c-97c5-46c3-ba5c-ceefe652398c
    Scheduled Worker running with ID: fc71f8dc-1785-43cd-9a44-1fe4e913ca6e
    Scheduled Worker running with ID: fca1bcea-97d9-4066-8b5a-8b5496ffed1e
 

..and the list grows everytime when I rebuild/restart the App in Android Studio or on my physical device.