doWork() for WorkManager called multiple times for OneTimeWorkRequest
Asked Answered
T

0

4

I have just started to explore WorkManager in my app. My app will mostly be offline, so all the data is stored locally using room db. As soon as the device gets connected to a network I want to sync local data to server and then get the latest data and sync local db again. This is my doWork() method implementation -

@NonNull
@Override
public Result doWork() {
    Worker.Result[] result = {Worker.Result.retry()};
    count = new CountDownLatch(1);

    Context context = getApplicationContext();
    try {
        new NetworkHelper.NetworkBuilder(context)
                .setRequestMethod(NetworkHelper.NetworkBuilder.RequestMethod.GET)
                .setTag(NetworkHelper.NetworkBuilder.TAG.FETCH)
                .setResponseListener((response, requestMethod, isError) -> {
                    Utils.printError("onResponse " + isError);
                    if (!isError) {
                        clearDataAndInsert(String.valueOf(response));
                    }
                })
                .build().callFetchData();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    try {
        count.await();
    } catch (InterruptedException e) {
        Utils.printDebug(e.getMessage());
    }

    Utils.printError(result[0].toString());

    return result[0];
}

in clearDataAndInsert() I am inserting the data that was fetched from server to local db using room and for this, I built my own callback listeners and checking if all my data is successfully inserted in the db using atmoic integer like this -

@Override
public void onTaskComplete() {
    int remaining = task.decrementAndGet();
    if (remaining == 0) {
        Data source = new Data.Builder()
                .putString("workInfo", "completed")
                .build();
        result[0] = Worker.Result.success(source);
        count.countDown();
    }
}

This is how I am enqueing the data -

Constraints constraints = new Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .setRequiresDeviceIdle(false)
            .build();

    Data source = new Data.Builder()
            .putString("workType", "OneTime")
            .build();

    OneTimeWorkRequest request = new OneTimeWorkRequest.Builder(SyncWorker.class)
            .setConstraints(constraints)
            .setInputData(source)
            .build();
WorkManager.getInstance(context).enqueue(request);

As you can see I am using CountDownLatch to wait for my fetch and insert in local db process to finish and then return success result from doWork(). But my problem is, my doWork gets called multiple times, I am guessing that's because result is returning as retry? But I cannot figure out why?

Tailor answered 24/5, 2020 at 10:53 Comment(4)
Have you figured it out yet? having same issue.Cushion
use enqueueUniqueWork() instead enqueue()Preponderant
@AnandTiwari, nice workSelfemployed
this : https://mcmap.net/q/677052/-unique-onetimeworkrequest-in-workmanagerBullace

© 2022 - 2024 — McMap. All rights reserved.