2

So per the documentation Firebase JobDispatcher is deprecated and should be migrated to use the WorkManager. I was following the migration guide which said the functionality implemented in a JobService should be migrated to a ListenableWorker. However I am stumped on how to implement startWork(), the guide only says

override fun startWork(): ListenableFuture<ListenableWorker.Result> {
    // Do your work here.
    TODO("Return a ListenableFuture<Result>")
}

I have done a lot of googling but i have not been able to figure out how to implement/use the ListenableFuture in this context to implement the functionality of the JobService, where I called jobFinished and returned a Boolean value to represent if work was still going on. Any help is appreciated

Community
  • 1
  • 1
StarterPack
  • 498
  • 1
  • 7
  • 28
  • 1
    This question was answered here: https://stackoverflow.com/questions/56176554/how-do-i-return-a-listenablefutureresult-with-work-manager-2-0 – Rahul May 16 '19 at 21:57

1 Answers1

1

You need to use ListenableWorker if you need to execute asynchronous code. There's a Threading in ListenableWorker documentation page that covers this:

If you wanted to execute some work based on an asynchronous callback, you would do something like this:

public class CallbackWorker extends ListenableWorker {

    public CallbackWorker(Context context, WorkerParameters params) {
        super(context, params);
    }

    @NonNull
    @Override
    public ListenableFuture<Result> startWork() {
        return CallbackToFutureAdapter.getFuture(completer -> {
            Callback callback = new Callback() {
                int successes = 0;

                @Override
                public void onFailure(Call call, IOException e) {
                    completer.setException(e);
                }

                @Override
                public void onResponse(Call call, Response response) {
                    ++successes;
                    if (successes == 100) {
                        completer.set(Result.success());
                    }
                }
            };

            for (int i = 0; i < 100; ++i) {
                downloadAsynchronously("https://www.google.com", callback);
            }
            return callback;
        });
    }
}

A simpler alternative, if you're using kotlin, is to use a CoroutineWorker class.
If what you need to execute is synchronous, using a Worker class is probably simpler and enough for your use case. This is documented in Threading in Worker.

pfmaggi
  • 6,116
  • 22
  • 43
  • This example is really incomplete and misleading. Though the documentation states that using Callback future is suffice for threading in listenable worker, but clearly that's not the case, because startWork does get called on the main thread – Axesh Ajmera Sep 04 '20 at 06:26
  • Would really appreciate on showing the right way to use threading in listenable worker as most API calls or SDKs have asynchronous methods – Axesh Ajmera Sep 04 '20 at 06:28