使用 RxJava 和 Retrofit 链接两个 Web 服务调用 [英] Chaining two web service calls using RxJava and Retrofit

查看:52
本文介绍了使用 RxJava 和 Retrofit 链接两个 Web 服务调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆