使用 RxJava 和 Retrofit 链接两个 Web 服务调用

Chaining two web service calls using RxJava and Retrofit

我正在使用 RxJava,Retrofit.My 基本要求是,我想链接两个 api 调用,一个接一个调用。从第一个 api 收到的响应用作调用第二个 api 时的输入。在互联网上阅读了一些东西后,我曾经使用平面图来实现这一点。在执行此操作时,我显示 loader.Sometimes 它运行平稳,但在某些情况下此加载程序会冻结。 DDMS 显示 "skipped 300 frames,Application may be doing too much work on its main thread" 的日志。我怀疑我的网络调用之一是主线程上的 运行。我无法弄清楚如何链接这两个调用,以便可以在后台顺利调用它们而不会妨碍我的主线程。任何帮助是极大的赞赏 。提前致谢 这是我到目前为止尝试过的

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(在你的[=16=上调用onNext(address) ]) 到另一个线程。但是,创建 地址 - 即您的 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