【问题标题】:multiple api request using retrofit and rx java使用改造和 rx java 的多个 api 请求
【发布时间】:2018-12-09 06:57:58
【问题描述】:

我是 android 新手,我有一个场景,我想从多个 api 获取数据。假设 api_aapi_bapi_capi_d。这些 api 彼此独立,但我想在混合回收器视图(水平和垂直)中显示来自这些 api 的数据。所以我想以这样的方式进行这些 api 调用,以便我可以一次获取每个 api 数据,以便我可以在回收器视图中显示。 我已经在使用 retrofit 2 但为此我不得不将它们一个一个链接起来,这非常冗长,我认为这不是一种可行的方法。我对RX JAVA知之甚少,但我只知道如何一次发出一个请求。请帮忙

【问题讨论】:

标签: android retrofit retrofit2 rx-java2 rx-android


【解决方案1】:

至少有两种方法可以实现这一点 -

1) 使用 RxJava Zip 运算符(用于并行请求)

获取所有可观察对象

Observable<ResponseType1> observable1 = retrofit.getApi_a();
Observable<ResponseType2> observable2 = retrofit.getApi_b();
Observable<ResponseType3> observable3 = retrofit.getApi_c();

压缩 observables 以获得最终的 observable

Observable<List<String>> result = 
Observable.zip(observable1.subscribeOn(Schedulers.io()), observable2.subscribeOn(Schedulers
            .io()), observable3.subscribeOn(Schedulers.io()), new Function3<ResponseType1, ResponseType2, ResponseType3, List<String>>() {
    @Override
    public List<String> apply(ResponseType1 type1, ResponseType2 type2, ResponseType3 type3) {
        List<String> list = new ArrayList();
        list.add(type1.data);
        list.add(type2.data);
        list.add(type3.data);
        return list;
    }
});

现在订阅结果 observable

result.observeOn(AndroidSchedulers.mainThread())
            .subscribeWith(new Observer<List<String>>() {
                @Override
                public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(List<String> s) {
                    Log.d(TAG, "s is the list with all the data");
                }

                @Override
                public void onError(Throwable e) {
                    Log.e(TAG, e.getMessage());
                }

                @Override
                public void onComplete() {

                }
            });

2) 使用 RxJava flatMap() 操作符。(依次请求)

这是简单的请求链接

    List<String> result = new ArrayList<>();
    Disposable disposable = retrofit.getApi_a()
            .subscribeOn(Schedulers.io())
            .flatMap((Function<ResponseType1, ObservableSource<ResponseType2>>) response1 -> {
                result.add(response1.data);
                return retrofit.getApi_b();
            })
            .flatMap((Function<ResponseType2, ObservableSource<ResponseType3>>) response2 -> {
                result.add(response2.data);
                return retrofit.getApi_c();
            })
            .map(response3 -> {
                result.add(response3.data);
                return response3;
            })
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeWith(new DisposableObserver<Response3>() {

                @Override
                public void onNext(Response3 response3) {
                    Log.d(TAG, "result variable will have all the data");
                }

                @Override
                public void onError(Throwable e) {
                    Log.e(TAG, e.getMessage());
                }

                @Override
                public void onComplete() {

                }
            });

【讨论】:

  • 如果任何一个 api 在 Zip 或 Flatmap 中失败会发生什么?
【解决方案2】:

为了组合多个 Observable,您可能需要考虑 Merge 运算符。 这将允许您将多个请求流组合成一个 Observable。

Merge 将在它们发出时将它们交错。如果顺序很重要,还有 Concat 会从每个 Observable 发出,然后再继续下一个。

Rx 文档

【讨论】:

  • 实际上我的要求不是合并它们而是获取单独的数据,但我希望并行执行而不是一个一个地执行
  • 我明白了,使用带有 Retrofit 的 Observables 你的请求将是异步的。您可以触发每个 API 请求并在响应返回时使用 OnNext 处理它们。
  • 你能给我一些链接,哪些改造和 rx java 用于多个 api 调用
  • 我有超过 4 个要合并的请求是什么?合并只接受 4
【解决方案3】:

Merge 运算符将多个 observable 合并为一个

设置 API 的 Base URL:

Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(Constants.BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .client(oktHttpClient.build())
                    .build();

现在为两个网络请求设置两个 observable:

Observable<JsonElement> Observable1 = ApiClient.getApiService().getApi_1();

Observable<JsonElement> Observable2 = ApiClient.getApiService().getApi_2();

现在我们使用 RxJava 的 merge 方法来组合我们的两个 Observable:

Observable.merge(Observable1, Observable2 )
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<JsonElement>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(JsonElement value) {
                        Log.d("RESPONSE", "onNext:=======" + value);
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {
                        Log.d("RESPONSE", "DONE==========");
                    }
                });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 1970-01-01
    • 2021-11-07
    • 1970-01-01
    • 2017-12-17
    • 2018-04-12
    • 2018-02-16
    相关资源
    最近更新 更多