我正在使用RxJava和Retrofit。我的基本要求是,我想链接两个api调用,这将被一个接一个地调用。从第一个api收到的响应在调用第二个api时用作输入。在互联网上阅读了一些东西之后我习惯了flatmap来实现这个目标。在执行此操作时,我正在显示装载器。有时它运行顺利但在某些情况下这个装载机冻结。 DDMS显示"跳过300帧的日志,应用程序可能在其主线程上做了太多工作"。我怀疑我的一个网络调用正在主线程上运行。我无法弄清楚如何链接这两个调用,以便可以在后台顺利调用它们而不会妨碍我的主线程。任何帮助是极大的赞赏 。提前致谢 这是我到目前为止所尝试的
private CompositeSubscription mSubscriptions = new CompositeSubscription();
Subscription subscription = Observable.just(getAddress())
.subscribeOn(Schedulers.newThread())
.flatMap(address -> mPlatformApi.secondWebService(address.getLatitude(),address.getLongitude())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(modelTwo ->
{
//updating My ui
}, throwable -> {
//Error Handling
});
mSubscriptions.add(subscription);
private android.location.Address getAddress(){
String addressString = "";//some Address String
Geocoder coder = new Geocoder(getActivity());
android.location.Address address=null;
try {
ArrayList<android.location.Address> addressList = (ArrayList<android.location.Address>) coder.getFromLocationName(addressString, 1);
if(addressList !=null && addressList.size()>0) {
address = addressList.get(0);
} else {
}
} catch (IOException e) {
e.printStackTrace();
}
return address;
}
//My Retrofit call
Observable<modelTwo> secondWebService(@Path("lat") double lat,@Path("lon") double lon);
答案 0 :(得分:6)
考虑一下:
final android.location.Address address = getAddress();
Subscription subscription = Observable.just(address) ...
这相当于您的代码,但是在RxJava参与并且有机会干预之前,还应该清楚getAddress()
被评估。换句话说,当您使用just
时,subscribeOn
只能移动地址的发射(在onNext(address)
上调用Subscriber
)另一个线程。但是,当你到达这一点时,地址的创建 - 即你的getAddress
- 已经发生在主线程上。
将getAddress
实际移至另一个主题的最简单方法是使用defer
:
Subscription subscription = Observable.defer(new
Func0<Observable<android.location.Address>>() {
@Override
public Observable<android.location.Address> call() {
return Observable.just(getAddress());
}
})
.subscribeOn(Schedulers.newThread())
.flatMap(address -> mPlatformApi.secondWebService(address.getLatitude(),address.getLongitude() )
.observeOn(AndroidSchedulers.mainThread())
.subscribe(modelTwo ->
{
//updating My ui
}, throwable -> {
//Error Handling
});
这样,整个Func0
将在newThread()
上执行 - 不仅是just
,还有getAddress
。