RxAndroid,结合多个Web调用

时间:2015-04-10 20:11:03

标签: java android rx-java rx-android

public List<Office> getOffices(){

    final List<Office> offices = new ArrayList<>();

    Observable observable = Observable.create(new Observable.OnSubscribe<Object>() {
        @Override
        public void call(Subscriber<? super Object> subscriber) {
            for(String[] of : backToArray(downloadWebPage("http://api.ataxcloudapp.com/v1/franchise/listing/?location=" + zip))) {
                offices.add(
                    new Office(
                        of,
                        backToArray(downloadWebPage("http://api.ataxcloudapp.com/v1/franchise/details/hours/" + of[0])).get(0),
                        downloadImage("https://www.ataxcloudapp.com/WebShared/uploads/franchises/" + of[0] + "/manager-photo.jpg?404=picture-placeholder.jpg"),
                        downloadImage("https://maps.googleapis.com/maps/api/staticmap?center=" + of[12] + ","+ of[13] +"&zoom=12&size=300x150&maptype=roadmap")
                    )
                );
            }
            subscriber.onCompleted();
        }
    });
    observable.subscribeOn(Schedulers.newThread())
              .observeOn(AndroidSchedulers.mainThread())
              .subscribe();
    return offices;
}

上述解决方案有点工作,加载结果需要很长时间,而且不一致。最后3次呼叫都依赖于第一次呼叫中给出的信息。我在这做错了什么?

1 个答案:

答案 0 :(得分:1)

首先,请注意,为了能够组成异步方法,它们都应该返回Observable<Something>而不是直接Something

因此,您应该将下载方法更改为

public Observable<Image> downloadImage(String url)
public Observable<WebPage> downloadWebPage(String url)

如果无法更改它们,请创建包装方法。

然后,您可以使用flatMapzip作为getOffices方法:

public Observable<Office> getOffices() {
   return downloadWebPage("office-url")
      .flatMap(new Func1<WebPage, Observable<Office>>() {
         public Observable<Office> call(WebPage webPage) {
            String url1 = "blah" + webPage.getInfo1();
            String url2 = "blah" + webPage.getInfo2();
            String url3 = "blah" + webPage.getInfo3();
            return Observable.zip(
               downloadWebPage(url1),
               downloadImage(url2),
               downloadImage(url3),
               new Func3<WebPage, Image, Image, Office>() {
                  public Office call(WebPage p, Image img1, Image img2) {
                     return new Office(p.getInfo0(), img1, img2);
                  }
               });
         }
      });
}