You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用RxJava链式调用Retrofit接口,关联电影与预告片数据?

用RxJava实现电影+预告片合并请求的正确姿势

刚好碰到过一模一样的需求,咱们一步步来拆解实现:

首先,你需要一个包装类来把电影和它的预告片绑定在一起——毕竟原有的Movie类应该没包含预告片字段对吧?

public class MovieWithVideos {
    private final Movie movie;
    private final List<Video> videos;

    public MovieWithVideos(Movie movie, List<Video> videos) {
        this.movie = movie;
        this.videos = videos;
    }

    // 记得加上getter方法,方便后续使用
    public Movie getMovie() { return movie; }
    public List<Video> getVideos() { return videos; }
}

接下来就是核心的RxJava流组合了,这里要用到几个关键操作符:

  1. 先获取全部电影列表:调用你的第一个Retrofit接口movieService.fetchAll()
  2. 拆分列表为单个电影:用flatMapIterable把Single<List<Movie>>转换成Observable<Movie>,这样就能逐个处理每部电影
  3. 并行获取预告片并合并数据:用flatMap(如果要串行处理就用concatMap)调用第二个接口获取预告片,然后用map把Movie和对应的List<Video>包装成MovieWithVideos
  4. 收集结果为列表:最后用toList()把所有MovieWithVideos重新组合成Single<List<MovieWithVideos>>

完整代码示例如下:

// 假设你的两个Retrofit服务实例是movieService和videoService
Single<List<MovieWithVideos>> fetchMoviesWithVideos() {
    return movieService.fetchAll()
            // 把电影列表拆成单个电影的Observable
            .flatMapIterable(movies -> movies)
            // 并行处理每部电影的预告片请求
            .flatMap(movie -> videoService.fetchByMovieId(movie.getId())
                    // 容错处理:如果某部电影的预告片请求失败,返回空列表,避免整个流崩溃
                    .onErrorReturnItem(Collections.emptyList())
                    // 把电影和预告片合并成包装类
                    .map(videos -> new MovieWithVideos(movie, videos)))
            // 把所有包装类收集成一个列表
            .toList()
            // 可选:如果是Android项目,切换到主线程更新UI
            .observeOn(AndroidSchedulers.mainThread())
            // 可选:指定请求在后台线程执行(Retrofit默认已经在后台,但显式指定更清晰)
            .subscribeOn(Schedulers.io());
}

关键细节说明:

  • flatMap vs concatMap:flatMap会并行发起所有预告片请求,效率更高;如果需要严格按电影顺序串行请求,就换成concatMap
  • 错误处理:onErrorReturnItem(Collections.emptyList())很重要,不然某一部电影的请求失败会导致整个流终止,这样即使个别请求失败,其他电影的数据依然能正常返回
  • 线程调度:subscribeOn(Schedulers.io())指定网络请求在IO线程执行,observeOn(AndroidSchedulers.mainThread())让最终结果在主线程回调(Android项目必备)

这样调用fetchMoviesWithVideos()就能得到包含所有电影及其预告片的列表了~

内容的提问来源于stack exchange,提问作者Dawid Fickenbaum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:21:05