WorkManger in Android is executing doWork() more than once
Asked Answered
T

2

5

I am using WorkManager to schedule some tasks but the problem is that work manager is executing those tasks { doWork() } more than once in a single call.


I am using:

'android.arch.work:work-runtime:1.0.0-alpha08'

I have tried using -alpha07,06,05,04. But I have same issue. Sometimes it even executes 5-6 times at once


Here is the code:

public class MyWorker extends Worker {

@NonNull
@Override
public Result doWork() {

    Log.i("CountWorker","0");
    sendNotification("Notice", "A notice was sent");
    return Result.SUCCESS;

}

This is the Activity

public class MyWorkerActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    final PeriodicWorkRequest pwr = new PeriodicWorkRequest
            .Builder(MyWorker.class, 16, TimeUnit.MINUTES)
            .setConstraints(Constraints.NONE)
            .build();

    WorkManager.getInstance().enqueue(pwr);

}
}

This is the result from Logcat:

09-24 16:44:35.954 22779-22816/com.simran.powermanagement I/CountWorker: 0
09-24 16:44:35.970 22779-22817/com.simran.powermanagement I/CountWorker: 0
09-24 16:44:35.977 22779-22818/com.simran.powermanagement I/CountWorker: 0
Theressa answered 24/9, 2018 at 20:59 Comment(0)
S
10

When you enqueue a PeriodicWorkRequest, that does not cancel any existing PeriodicWorkRequest that you have previously enqueued. Therefore as you have written your app, every time your activity starts, you add yet periodic work request, slowly going from 1 to 2 to 3 onward.

You instead want to use enqueueUniquePeriodicWork():

This method allows you to enqueue a uniquely-named PeriodicWorkRequest, where only one PeriodicWorkRequest of a particular name can be active at a time. For example, you may only want one sync operation to be active. If there is one pending, you can choose to let it run or replace it with your new work. The uniqueWorkName uniquely identifies this PeriodicWorkRequest.

With code such as:

final PeriodicWorkRequest pwr = new PeriodicWorkRequest
        .Builder(MyWorker.class, 16, TimeUnit.MINUTES)
        .setConstraints(Constraints.NONE)
        .build();

WorkManager.getInstance().enqueueUniquePeriodicWork(
    "my_worker",
    ExistingPeriodicWorkPolicy.REPLACE,
    pwr);
Subkingdom answered 25/9, 2018 at 2:58 Comment(0)
D
0

For OneTimeWorkRequest using version 1.0.0-beta01

WorkManager.getInstance()
            .beginUniqueWork("Unique", ExistingWorkPolicy.KEEP, oneTimeWorkRequest)
            .enqueue();

Cancel the existing sequence and REPLACE it with the new one.
KEEP the existing sequence and ignore your new request.
APPEND your new sequence to the existing one, running the new sequence's first task after the existing sequence's last task finishes

Official Documentation. https://developer.android.com/topic/libraries/architecture/workmanager/advanced

Dutyfree answered 9/1, 2019 at 12:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.