我正在使用Retrofit和RxJava来执行一些后台任务。代码如下所示:
public class MyLoader{
public Observable<MyData> getMyData(){
return setupHelper().flatMap(new Func1<MyHelper, Observable<MyData>>() {
@Override
public Observable<MyData> call(MyHelper myHelper) {
return queryData(myHelper);
}
});
}
private Observable<MyData> queryData(MyHelper myHelper){
...
}
private Observable<MyHelper> setupHelper(){
return Observable.create(new Observable.OnSubscribe<MyHelper>() {
@Override
public void call(final Subscriber<? super MyHelper> subscriber) {
try{
MyHelper helper = makeRetrofitCall();//Using Retrofit blocking call to get some data
subscriber.onNext(helper);
subscriber.onCompleted();
}catch(RetrofitError e){
subscriber.onError(e)
}
}
}
}
}
由于此行NetworkOnMainThread
异常导致RetrofitError失败:
MyHelper helper = makeRetrofitCall();//Using Retrofit blocking call to get some data
订阅我的Observable:
myLoader.getMyData()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<MyData>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(MyData inventory) {
}
});
根据Rx文档flatMap
不能在任何后台线程上运行。我的问题是如何确保整个getMyData()
方法在后台运行。
答案 0 :(得分:4)
我只是在observeOn(Schedulers.newThread())
之前添加flatMap
并且它有效!
答案 1 :(得分:1)
这只会在管道中向后台线程移动一步:
Observable<Integer> vals = Observable.range(1,10);
vals.flatMap(val -> Observable.just(val)
.subscribeOn(Schedulers.computation())
.map(i -> intenseCalculation(i))
).subscribe(val -> System.out.println(val));
答案 2 :(得分:0)
当你在主线程中创建MyLoader对象时,很有可能同时执行Observable.create(或者在你的代码之前的某个地方(?))。如果是这样的话,.subscribeOn(Schedulers.io())
对改变线程没有影响。
您可以尝试使用.defer()
包装.create()以确保仅在订阅时创建Observable。
e.g。 defer(() -> create(....))