我正在尝试在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.创建异步任务时的最佳做法是什么?
提前致谢。
答案 0 :(得分:20)
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
类似。
嗯,这取决于你和你想要的行为。有时您希望异步代码立即开始运行(在这种情况下,您可能希望使用其中一个运算符来缓存它)。我绝对会考虑使用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