Android中的RxJava异步任务

时间:2015-04-16 09:22:14

标签: android android-asynctask rx-java

我正在尝试在Android中使用RxJava实现异步任务。 我尝试了以下代码,但它没有用。它在UI线程上执行。我使用的是以下版本的RxAndroid 0.24.0。

try {
            Observable.just(someMethodWhichThrowsException())
                    .subscribeOn(Schedulers.newThread())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(s -> onMergeComplete());
        } catch (IOException e) {
            e.printStackTrace();
        }

但是,以下内容对我来说是异步的。

Observable observable = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                try {
                    someMethodWhichThrowsException();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                subscriber.onCompleted();
            }
        });
        observable.subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread()).subscribe();

我想了解以下内容:  1.它们之间有什么区别?  2.创建异步任务时的最佳做法是什么?

提前致谢。

2 个答案:

答案 0 :(得分:20)

  1. 他们之间有什么区别?
  2. Observable.just(someMethodWhichThrowsException())
        .subscribeOn(Schedulers.newThread())
    

    这相当于以下内容:

    Object someResult = someMethodWhichThrowsException();
    Observable.just(someResult)
        .subscribeOn(Schedulers.newThread())
    

    如您所见,这使得同步方法首先调用,然后将其传递给Observable.just以成为Observable。

    Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                ...
            }
        })
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe();
    

    但是,此方法将在订阅上的call中运行代码。您已经告诉它您要订阅新线程(subscribeOn(Schedulers.newThread())),因此订阅发生在新线程上,并且在订阅时运行的代码(call块)获得也在那个线程上运行。这与调用Observable.defer类似。

    1. 创建异步任务时的最佳做法是什么?
    2. 嗯,这取决于你和你想要的行为。有时您希望异步代码立即开始运行(在这种情况下,您可能希望使用其中一个运算符来缓存它)。我绝对会考虑使用Async Utils库。

      其他时候,您希望它仅在订阅时运行(这是示例中的行为) - 例如,如果有副作用,或者您不关心它&# 39; s运行,只是想使用内置函数从UI线程中获取一些东西。 Observable.defer {{1}}在转换为Rx期间,在获取旧代码并将其从UI线程中删除时非常方便。

答案 1 :(得分:11)

使用RxJava Async Utils库中的Async.start()。这将调用您在另一个线程上提供的功能。

示例:

Observable<String> observable = Async.start(new Func0<String>() {
    @Override
    public String call() {
        try {
            return someMethodWhichThrowsException();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
});

如您所知,已检查的异常必须包含在RuntimeExceptions中。

另见https://github.com/ReactiveX/RxJava/wiki/Async-Operators#start