I think there are three problems.
1) You’re creating a new periodic work every time you enqueue
myWork
to the WorkManager
Instance.
Try it, the logic in the doWork()
method of your MyWorker.class
runs once the first time, runs twice the second time. You most likely added 11 works to Work Manager and this is why it ran 11 times, the last time you checked. If you create new works and add it to the work manager then the number of times myWork
runs increases.
Similar to Job Scheduler, you have to check if the Work exists or not before you add it to the Work Manager.
Sample Code:
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");
}
});
In the above sample, I'm using a unique tag TAG_PERIODIC_WORK_REQUEST
to identify my periodic work and checking if it exists or not before creating it.
2) Your work may not be running when the app is killed.
What is the brand, you're testing on? Is it Xiaomi? Have you tested it on multiple other brands and ended up with the same result?
Was it in Doze mode? And how are you validating that the work is not running when you set 24 hours time?
Work Manager provides backward compatibility but still, you need to handle the device specific logic. On Xiaomi devices, similar to Job Scheduler (or Firebase Job Dispatcher or Alarm), the periodic work stops when the app is killed.
3) I just think the PeriodicWorkRequest
provided by WorkManager
is buggy.
I have been testing it since the start of the previous week on multiple devices. I created a work when the app was launched the first time and didn't open it for three days. It ran once the first time, two times when the second sync was triggered and in between, it increased to 13 times, dropped to 1 time, 4 times etc.,.
In another test, I created a work with the below code during the first install and removed the code from the second install. During this test, Even if the work successfully completed, the work ran every time, the app is opened after killing it.
final PeriodicWorkRequest periodicWorkRequest =
new PeriodicWorkRequest.Builder(SyncWorker.class, 30, TimeUnit.MINUTES)
.addTag("periodic-work-request")
.build();
// Queue the work
WorkManager.getInstance().enqueue(periodicWorkRequest);
I understand that since it is still in alpha. I don't think you should be using it in production.