217

在 WorkManager 中处理异步任务

 5 years ago
source link: http://wl9739.github.io/2019/02/07/在WorkManager中处理异步任务/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

WorkManager 是 Android Jetpack 中的新组件,用于负责管理后台任务。关于这个组件的介绍就不多说了,网上到处都是,这里分享一下在 WorkManager 中处理异步任务的方法。

我们知道,在 WorkManager 中,处理任务的方式是创建一个继承自 Worker 的任务类,实现 doWork() 方法,并在这个方法中实现我们自己的任务,然后返回 Result.success()Result.failure() 来表示任务执行成功或者失败。在这里, doWork() 方法中的任务应该是同步的,这是很自然的,因为 doWork() 方法本身就是在子线程中执行,因此可以在 doWork() 方法中同步执行耗时操作。

但是些情况,我们想要执行的是异步任务,在 WorkManager 中,有两种比较好的处理异步任务的方案。

RxWorker

很多时候我们会使用 RxJava 来处理数据。幸运的是,我们可以使用 RxWorker 来处理异步任务。

dependencies {
   ...
   implementation "android.arch.work:work-runtime:1.0.0-beta05"
   implementation "android.arch.work:work-rxjava2:1.0.0-beta05"
}

然后,将之前集成 Work 的类改为继承 RxWorker ,然后实现 createWork() 方法,基本结构如下:

public class AsyncWorker extends RxWorker {

    public AsyncWorker(Context appContext, WorkerParameters workerParams) {
        super(appContext, workerParams);
    }

    @Override
    public Single<Result> createWork() {
        return remoteService.getMySingleResponse()
                .doOnSuccess(new Consumer() {
                    @Override
                    public void accept(Object object) throws Exception {
                        // 处理任务
                    }
                })
                .map(new Function() {
                    @Override
                    public Object apply(Object object) throws Exception {
                        return Result.success();
                    }
                })
                .onErrorReturn(new Function() {
                    @Override
                    public Object apply(Object object) throws Exception {
                        return Result.failure();
                    }
                });
    }
}

很简单是吧?有一点要注意的是, createWork() 方法默认是在主线程中执行的,如果 10 分钟没有结束任务,就会自动取消。

ListenableWorker

当我们去查看 RxWorker 的源码时,就可以发现它是继承了 ListenableWorker 类,其实 Worker 也是通过继承 ListenableWorker 实现的。 因此,我们可以通过自定义 ListenableWorker 来实现相同的功能。

看一下 Worker 的源码,很简单:

public abstract class Worker extends ListenableWorker {
    SettableFuture<Result> mFuture;
    public Worker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @WorkerThread
    public abstract @NonNull Result doWork();
    @Override
    public final @NonNull ListenableFuture<Result> startWork() {
        mFuture = SettableFuture.create();
        getBackgroundExecutor().execute(new Runnable() {
            @Override
            public void run() {
                Result result = doWork();
                mFuture.set(result);
            }
        });
        return mFuture;
    }
}

可以里面主要使用了 SettableFuture 这个类,在 startWork() 里面先创建了 SettableFuture 对象,然后开了一个子线程,在子线程里面执行 doWork() 方法,完了就使用 mFuture.set() 方法将 Result 返回。

因此我们也可以模仿 Worker 类的写法,来实现自己的异步处理,简单地模板代码如下:

public class AsyncWorker extends ListenableWorker {
    private SettableFuture<Result> mFuture;
    public AsyncWorker(Context appContext,WorkerParameters workerParams) {
        super(appContext, workerParams);
    }

    @Override
    public ListenableFuture<Result> startWork() {
        mFuture = SettableFuture.create();
        doSomeAsyncWork(new AsyncListener() {
            @Override
            public void success() {
                mFuture.set(Result.success());
            }
            
            @Override
            public void fail() {
                mFuture.set(Result.failure());
            }
        });
        return mFuture;
    }
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK