RxJava如何将两个列表的两个和响应称为异步?

时间:2017-07-25 17:32:50

标签: android rx-java retrofit2

我有两个使用Retrofit2调用的不同对象列表。这两个列表工作正常并返回所有元素OK。第二部分是两个对象都有一个属性“importe”(代表钱),所以首先我需要将每个列表的对象相加作为小计,然后将两个列表的小计相加得到Total(totalList1 + totalList2)并在TextView

中显示此值

我的问题是,当我使用两个异步请求时,我无法对小计求和。我的代码可以找到here

我尝试使用retrofit2同步请求,但收到错误:

  

android.os.NetworkOnMainThreadException

所以其他人建议我使用RxJava。有人可以详细解释如何在这种情况下实施?没有完美的严格语法,请告诉我,例如:

//here create rxJava adapter
 ......
// here call the first request for the first List<ObjectA>
  then
//here call the second request for the second List<ObjectB>
.... 
//and here get the subtotal of each list and sum to get total and put in textview...

欢迎任何建议和帮助,提前谢谢!

我的sdkversion:

minSdkVersion 21

targetSdkVersion 25

2 个答案:

答案 0 :(得分:0)

好的,我总结一下步骤:

第1步

在您的gradle文件中添加转换器工厂

compile 'com.squareup.retrofit2:retrofit:x.x.x' // same version 
compile 'com.squareup.retrofit2:adapter-rxjava2:x.x.x' // same version 

第2步

您必须将Retrofit的返回类型转换为Observable,因此Retrofit构建器应附加一个调用适配器。

adapterFactory = RxJava2CallAdapterFactory.create();
Retrofit.Builder()
               .baseUrl(baseUrl)
               .addCallAdapterFactory(adapterFactory)
               .build();

第3步

在改装界面中,替换:

Call<List<T>> getList()

进入

Single<List<T>> getList()

第4步

然后你可以使用zip运算符,它封装了observable并在两者完成时发出异步结果。

编辑:我根据您的需要调整了类型

    Single<List<Object1>> obsList1 = api.getList1();
    Single<List<Object2>> obsList2 = api.getList2();

    Single.zip(obsList1, obsList2, new BiFunction<List<Object1>, List<Object2>, String>() {
        @Override
        public String apply(List<Object1> list1, List<Object2> list2) throws Exception {
            double tot1 = 0, tot2 = 0;
            for(Object1 o : list1){
                tot1 += o.getMoney();
            }
            for(Object2 o : list2){
                tot2 += o.getMoney();
            }
            return String.valueOf(tot1 + tot2);
        }
    });

答案 1 :(得分:0)

首先使用运算符和订阅计算调度程序移出主线程。

然后使用flatMap,在flatMap中进行两次服务调用,然后对生成的observables应用flatMap,这些observable会发出对象列表以获得每个列表的小计

然后使用zip获取总数

 Observable.just(1).subscribeOn(Schedulers.computation()).flatMap( dummy -> {

    Observable<List<ObjectA>> objectAObservable =  retrofitService.firstCall().subscribeOn(Schedulers.io());
    Observable<List<ObjectB>> objectBObservable = retrofitService.secondCall().subscribeOn(Schedulers.io());

    Observable<Float> subTotalA =objectAObservable.flatMap(lst -> {
        float subTotal = 0;
        for(obj : lst){
            subTotal = subTotal + obj.getMoney();
        }

        return Observable.just(subTotal );});


    Observable<Float> subTotalB = objectBObservable.flatMap(lst -> {
        float subTotal = 0;
        for(obj : lst){
            subTotal = subTotal + obj.getMoney();
        }

        return Observable.just(subTotal );});

    return Observable.zip(subTotalA, subTotalB, new BiFunction<Float, Float, String>() {
            @Override
            public String apply(Float subTotalA, Float subTotalB) throws Exception {
                return String.valueOf(subTotalA + subTotalA);
            }
        });
    }).observeOn(AndroidSchedulers.mainThread())
    .subscribe(total -> LOGGER.info("total money - to be set on TextView.. "+total));