WorkManager系列(十五)Threading in ListenableWorker

In certain situations, you may need to provide a custom threading strategy. For example, you may need to handle a callback-based asynchronous operation. In this case, you cannot simply rely on a Worker because it can't do the work in a blocking fashion. WorkManager supports this use case with ListenableWorkerListenableWorker is the lowest-level worker API; WorkerCoroutineWorker, and RxWorker all derive from this class. A ListenableWorker only signals when the work should start and stop and leaves the threading entirely up to you. The start work signal is invoked on the main thread, so it is very important that you go to a background thread of your choice manually.

The abstract method ListenableWorker.startWork() returns a ListenableFuture of the Result. A ListenableFuture is a lightweight interface: it is a Future that provides functionality for attaching listeners and propagating exceptions. In the startWork method, you are expected to return a ListenableFuture, which you will set with the Result of the operation once it's completed. You can create ListenableFutures one of two ways:

  1. If you use Guava, use ListeningExecutorService.
  2. Otherwise, include councurrent-futures in your gradle file and use CallbackToFutureAdapter.

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;
        });
    }
}

What happens if your work is stopped? A ListenableWorker's ListenableFuture is always cancelled when the work is expected to stop. Using a CallbackToFutureAdapter, you simply have to add a cancellation listener, as follows:

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());
                    }
                }
            };

            completer.addCancellationListener(cancelDownloadsRunnable, executor);

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值