我有两个使用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
答案 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));