使用翻新和rx Java的多个api请求

时间:2018-06-30 07:07:35

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

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

3 个答案:

答案 0 :(得分:6)

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

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

获取所有可观察物

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

压缩可观察对象以获得最终可观察对象

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;
    }
});

现在订阅所得的可观察结果

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() {

                }
            });

答案 1 :(得分:0)

要合并多个Observable,您可能需要考虑 Merge 运算符。 这样一来,您就可以将多个请求的流合并为一个Observable。

合并将在它们发出时交错它们。如果顺序很重要,那么 Concat 将从每个Observable发出,然后继续下一个。

Rx文档

答案 2 :(得分:0)

Merge运算符将多个可观察值合并为一个

设置API的基本URL:

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

现在为两个网络请求设置两个可观察对象:

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

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

现在,我们使用RxJava的mergemethod结合我们的两个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==========");
                    }
                });