WorkManager executing enqueueUniquePeriodicWork() multiple times at once?
Asked Answered
M

3

6

I'm new to this so do let me know if the question is badly worded! I have an Android app that needs to execute a task roughly every 15 minutes even if the phone is on lock. The context is: - Im targeting SDK 23 or higher - The task 1) takes the user's location 2) makes a call to an HTTPS API using OKHttpClient, then 3) sends the results to a Firestore database

I'm using WorkManager to try to achieve this goal. However, the problem is every time it executes, it does so 8 - 9 times and it is very irregular in timing. I can see this from the Firestore entries and Logcat.

Is WorkManager even the right way to go about this task? I am using

implementation "androidx.work:work-runtime:2.0.1"
import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkManager;
import androidx.work.ExistingPeriodicWorkPolicy;

I see others have had this issue: Android Worker execute the job multiple times

//In MainActivity.java: 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(
                PeriodicReadings.class, 15, TimeUnit.MINUTES).build();

        WorkManager.getInstance().enqueueUniquePeriodicWork("PWR", ExistingPeriodicWorkPolicy.REPLACE, periodicWorkRequest);

//In PeriodicReadings.java:

    @NonNull
    @Override
    public Result doWork() {
        getReadings(); //work to be done 
        return Result.success();
    }

Every 15 minutes I expected a reading to appear in the Firestore database, but instead I see batches of 8 - 9 readings appear at irregular intervals varying every 15minutes - 2 hours.

I have tried clean and rebuild, invalidating and restarting cache, and also reloading the app on the phone.

Minnow answered 20/6, 2019 at 12:39 Comment(2)
did you figure it out ?Detriment
as @user1712810 suggested you should swap out the ExistingPeriodicWorkPolicy.REPLACE with ExistingPeriodicWorkPolicy.KEEP. However even after doing so I am experiencing the same issue as you. Our analytics are going all over the place on specific devices doing duplicate work in a difference span of ~10 seconds. The back off period is set to Linear with a minimum back off time of 10 seconds but we never call Result.retry() so its really confusing what is going on.Heavyfooted
R
1

Try this out:

WorkManager.getInstance().enqueueUniquePeriodicWork("PWR",ExistingPeriodicWorkPolicy.KEEP, periodicWorkRequest);

KEEP: If a previous worker exists, your new attempt is simply ignored, else your new worker is enqueued.

REPLACE: If a previous worker exists, it is cancelled, leading to a state CANCELLED for it. Then or else, your new worker is enqueued.

Rickyrico answered 9/5, 2020 at 1:25 Comment(0)
H
0

Well it's not the best way but it would be better if you cancel all your Work managers task before starting your WorkManager.getInstance().enqueueUniquePeriodicWork("PWR", ExistingPeriodicWorkPolicy.REPLACE, periodicWorkRequest);

OR

Check if there is already a Workmanager is in queue then don't start it again in OnCreate.

Hep answered 8/5, 2020 at 22:58 Comment(0)
D
-2

You are enqueueing work in your Activity#onCreate() so every time your activity gets created you are enqueuing a new WorkRequest. Which is why you will see multiple instances of the work request. You probably want the enqueueUniquePeriodicWork() API.

Deni answered 21/6, 2019 at 3:38 Comment(1)
I see - so is my code above "WorkManager.getInstance().enqueueUniquePeriodicWork("PWR", ExistingPeriodicWorkPolicy.REPLACE, periodicWorkRequest);" not being used correctly?Minnow

© 2022 - 2024 — McMap. All rights reserved.