使用Retrofit和RxJava同时组合多个API请求

时间:2016-01-12 03:53:04

标签: android retrofit rx-java

我目前正在开发我的Android应用,并且在我的Home Activity中显示从API检索的数据时遇到问题。这是我家庭活动的设计。

enter image description here

在该页面上,我想显示三个数据:最新消息,最受欢迎的新闻和类别。每个数据都来自不同的API。因此,显示数据时有三个API请求。

我想要的场景是同时执行所有请求,在获取此类数据时显示进度条,并在成功获取此三个API的所有数据时关闭进度条。如果我获得了最新的新闻数据,那么在成功获得热门新闻和类别数据之前,进度条将不会被取消。并且当成功获得最新的新闻数据和类别数据时,但是在获得热门新闻时我遇到了问题,那么所有数据都不会显示在页面上,并且页面将显示错误消息。

我正在使用改造来访问我的API。我也尝试将它与RxJava结合使用以访问API。我尝试过使用RxJava组合序列方法,比如combineLatest,merge,但我发现的问题是它不能同时组合两个以上的请求/序列。所以我还没有遇到解决方案。

这种情况有什么好的解决方案吗?

1 个答案:

答案 0 :(得分:0)

我的初始(不正确)答案在下面得到了解释。对不准确的道歉。

combineLatest似乎做了你想做的事。问题下的当前评论有正确的想法,但我认为combineLatest的排放处理可以稍好一些,所以这是我对此的看法。

Observable.combineLatest(
            api.getLatest(),
            api.getPopular(),
            api.getCategories(),
            NewsReaderViewModel::new)
            // This is very simple progress bar logic, and will actually break if this code
            // errors. Handling of the progress bar should be slightly different, but for the
            // sake of this example, I'm going to keep it as simple as possible.
            .doOnSubscribe(disposable -> loadingProgressBar.setVisibility(View.VISIBLE))
            // Depending on your requirements, you might not need to continue observing this
            // stream. If you expect your results are going to continue to be updated, then
            // you won't want to add this next line, but I don't imagine this data is going to
            // live update.
            .firstElement()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(this::displayResults, out::println);

我创建了NewsReaderViewModel来保存结果,因为您可能希望对结果执行某些逻辑,并且在使用ArrayList解决方案时无法以合理的方式执行此操作。这是NewsReaderViewModel类。它非常简单,只包含三个字符串列表。

static final class NewsReaderViewModel {

    final List<String> latest;
    final List<String> popular;
    final List<String> categories;

    NewsReaderViewModel(List<String> latest, List<String> popular, List<String> categories) {
        this.latest = latest;
        this.popular = popular;
        this.categories = categories;
    }
}

我省略了其余的代码,但是这里有一个指向Github存储库的链接,其中包含您将能够克隆和运行的完整示例。如果您有任何问题,请告诉我,我希望这有帮助!

Here is the Github link 我还会上传一段关于答案背后的思维过程的YouTube视频,并在该视频可用后将其关联起来。有时甚至更多地看到答案背后的思想和错误以及过程,而不仅仅是答案本身。

我认为你可能真的想使用zip而不是结合最新版本。 Zip将等待所有压缩的observable发出一次。这听起来更接近你的要求。

以下是zip文档:http://reactivex.io/documentation/operators/zip.html

您将订阅生成的zip流,并在那里显示UI的结果并隐藏进度条。如果你使用combineLatest,你必须检查结果订阅内容是否为null,这不是惯用的Rx