使用 RxJava 和 Retrofit 链接两个 Web 服务调用 [英] Chaining two web service calls using RxJava and Retrofit
问题描述
我正在使用 RxJava 和 Retrofit.我的基本要求是,我想链接两个 api 调用,它们将一个接一个地被调用.在调用第二个 api 时,将从第一个 api 收到的响应用作输入.在互联网上阅读了一些东西后,我曾经使用平面地图来实现这一点.在执行此操作时,我正在显示加载程序.有时它运行顺利,但在某些情况下此加载程序冻结.DDMS 显示跳过 300 帧,应用程序可能在其主线程上做了太多工作"的日志.我怀疑我的一个网络调用正在主线程上运行.我无法弄清楚如何链接这两个调用,以便可以在后台顺利调用它们而不会妨碍我的主线程.任何帮助是极大的赞赏 .提前致谢这是我迄今为止尝试过的
I am using RxJava and Retrofit.My basic requirement is,i want to chain two api calls, which will get called one after one another. Response received from first api is used as input while calling second api. After reading some stuff on internet i used to flatmap to achieve this. While carrying out this operation i am showing loader.Sometimes it runs smoothly but on some occasions this loader freezes. DDMS shows log of "skipped 300 frames,Application may be doing too much work on its main thread". I suspect one of my network call is running on main thread. I am not able to figure out how to chain these two calls so that they can be smoothly called in background without hampering my main thread. Any help is greatly appreciated . Thanks in advance This is what i have tried so far
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);
推荐答案
考虑一下:
final android.location.Address address = getAddress();
Subscription subscription = Observable.just(address) ...
这等价于您的代码,但还应明确说明 getAddress()
在涉及 RxJava 并有机会干预之前被评估.换句话说,当你使用just
时,subscribeOn
只能移动地址的emission(调用onNext(address)
在您的 Subscriber
) 到另一个线程.但是,当您到达这里时,地址的创建——即您的getAddress
——已经在主线程上发生了.
This is equivalent to your code, but should also make it clear that getAddress()
is evaluated before RxJava is involved and has had any chance to intervene. In other words, when you use just
, the subscribeOn
can only move the emission of the Address (calling onNext(address)
on your Subscriber
) to another thread. However, the creation of the Address - that is, your getAddress
- will already have happened on the main thread when you get to this point.
实际将 getAddress
移动到另一个线程的最简单方法是使用 defer
:
The easiest way to actually move getAddress
to another thread is to use 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代码>.
This way, the whole Func0
will be executed on newThread()
- not only the just
but also the getAddress
.
这篇关于使用 RxJava 和 Retrofit 链接两个 Web 服务调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!