【问题标题】:RxAndroid, combining multiple web callsRxAndroid,结合多个网络调用
【发布时间】:2015-07-23 06:32:46
【问题描述】:
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 次通话都取决于第一次通话中给出的信息。我在这里做错了什么?

【问题讨论】:

    标签: java android rx-java rx-android


    【解决方案1】:

    首先,请注意,为了能够组合异步方法,它们都应该返回Observable&lt;Something&gt;,而不是直接返回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);
                      }
                   });
             }
          });
    }
    

    【讨论】:

    • 我认为这是一个很好的解决方案。一些额外的注意事项......一般避免Observable.create。 (几乎)总有一种方法可以组合你需要的东西,就像 Samuel 在这里所做的那样,而不需要管理你自己的 observable 的额外开销。例如,您的自定义 Observable 不会检查退订。另外,如果这用于显示项目列表,我建议使用 observable 来获取图像 URL 字符串,但不要下载它们。使用 glide github.com/bumptech/glide 或 Picasso square.github.io/picasso 之类的东西来管理将图像加载到视图中。
    猜你喜欢
    • 1970-01-01
    • 2020-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-31
    • 2019-02-04
    • 1970-01-01
    • 2013-12-20
    相关资源
    最近更新 更多