Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/225.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何在RxJava2中等待项目列表完成?_Android_Rx Java2 - Fatal编程技术网

Android 如何在RxJava2中等待项目列表完成?

Android 如何在RxJava2中等待项目列表完成?,android,rx-java2,Android,Rx Java2,如果我对如何使用RxJava2缺乏基本了解,请提前道歉,因为在我看来,这应该是非常基本的。谷歌搜索失败让我绞尽脑汁,所以欢迎任何资源推荐。为了清晰起见,我选择使用“净化”的变通代码表示 问题描述 我有一个RxJava2函数asyncCallForList(),它返回一个可能。此列表中的每个CustomClass对象仅填充了几个基本字段(例如,源数据库仅包含每个项目的唯一标识符和标题字符串) 每个项目所需的完整数据位于另一个数据库位置,使用另一个函数asyncCallForItem(uid)检索

如果我对如何使用RxJava2缺乏基本了解,请提前道歉,因为在我看来,这应该是非常基本的。谷歌搜索失败让我绞尽脑汁,所以欢迎任何资源推荐。为了清晰起见,我选择使用“净化”的变通代码表示


问题描述 我有一个RxJava2函数
asyncCallForList()
,它返回一个
可能
。此列表中的每个
CustomClass
对象仅填充了几个基本字段(例如,源数据库仅包含每个项目的唯一标识符和标题字符串)

每个项目所需的完整数据位于另一个数据库位置,使用另一个函数
asyncCallForItem(uid)
检索该位置,该函数基于唯一标识符返回一个
Maybe
,其中封装的
CustomClass
包含所有所需数据。此函数将为
asyncCallForList()
返回的列表中的每个项目调用

所需的功能是在填充列表中的所有对象后更新我的UI。


解决办法#1 很容易在附加到初始
Maybe
doOnSuccess()
中循环得到的数组列表,然后在后续异步调用返回的
Maybe
上的
doOnSuccess()
中更新我的UI。这不是一个可接受的解决方法,因为将有未知数量的UI更新(返回的初始列表可能包含任意数量的项),并且会影响性能


解决办法#2 这得到了期望的结果,但感觉是错误的做法——我怀疑有一个更优雅的RxJava2解决方案。基本上,我创建了一个定制的
Observable
,在其中循环遍历列表中的项目,并获取每个项目的完整数据。但是,我没有在每次填充
CustomClass
项时更新UI,而是增加一个计数器,然后检查计数器是否超过或等于初始列表大小。当满足此条件时,我调用可观察发射器的
onComplete()
方法,并在那里更新UI

private void fetchRemoteDataAndUpdateUi() {

    //Counter reset to zero before any asynchronous calls are made.
    int count = 0;

    Maybe<ArrayList<CustomClass>> itemList = asyncCallForList();
    Consumer<ArrayList<CustomClass>> onListReturnedSuccess;

    onListReturnedSuccess = new Consumer<ArrayList<CustomClass >>() {
        @Override
        public void accept(ArrayList<CustomClass> list) throws Exception {
            //Custom observable created here, in which the resulting array list is processed.
            listObservable = Observable.create(new ObservableOnSubscribe<CustomClass>() {
                @Override
                public void subscribe(final ObservableEmitter<CustomClass> e) throws Exception {
                    for (CustomClass customClass : list) {
                        final CustomClass thisCustomClass = customClass;
                        //Call to get full data on list item called here.
                        asyncCallForItem(customClass.getUid())
                                .doOnSuccess(new Consumer<CustomClass>() {
                                    @Override
                                    public void accept(CustomClass customClass) throws Exception {
                                        thisCustomClass.update(customClass);
                                        e.onNext(thisCustomClass);
                                        count++;
                                        if (count >= list.size()) {
                                            e.onComplete();
                                        }
                                    }
                                }).subscribe();
                    }
                }
            });

            listObservable
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribeOn(Schedulers.io())
                    .subscribe(new Observer<CustomClass>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                        }

                        @Override
                        public void onNext(CustomClass customClass) {
                            //Here I add the populated CustomClass object to an ArrayList field that is utilised by the UI.
                            listForUi.add(customClass);
                        }

                        @Override
                        public void onError(Throwable e) {

                        }

                        @Override
                        public void onComplete() {
                            //Here the UI is finally updated once all CustomClass objects have been populated.
                            updateUi();
                        }
                    });
        }
    };


    //Kick everything off.
    itemList.doOnSuccess(onListReturnedSuccess).subscribe();
}
private void fetchRemoteDataAndUpdateUi(){
//在进行任何异步调用之前,计数器重置为零。
整数计数=0;
可能itemList=asyncCallForList();
只有消费者才能获得成功;
onListReturnedSuccess=新消费者(){
@凌驾
public void accept(ArrayList列表)引发异常{
//在此处创建的自定义可观察对象,在其中处理生成的数组列表。
listObservable=Observable.create(newobservableOnSubscribe(){
@凌驾
public void subscribe(最终可观察提交者e)引发异常{
用于(CustomClass CustomClass:列表){
最终定制类thisCustomClass=定制类;
//调用以获取此处调用的列表项的完整数据。
asyncCallForItem(customClass.getUid())
.doOnSuccess(新消费者(){
@凌驾
public void accept(CustomClass CustomClass)引发异常{
thisCustomClass.update(customClass);
e、 onNext(此自定义类);
计数++;
如果(计数>=list.size()){
e、 onComplete();
}
}
}).subscribe();
}
}
});
可观察列表
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.订阅(新观察员){
@凌驾
认购的公共无效(一次性d){
}
@凌驾
public void onNext(CustomClass CustomClass){
//在这里,我将填充的CustomClass对象添加到UI使用的ArrayList字段中。
listForUi.add(customClass);
}
@凌驾
公共无效申报人(可丢弃的e){
}
@凌驾
未完成的公共空间(){
//在这里,一旦填充了所有CustomClass对象,UI将最终更新。
updateUi();
}
});
}
};
//启动一切。
itemList.doOnSuccess(onListReturnedSuccess.subscribe();
}

flatMap
it

asyncCallForList()
.subscribeOn(Schedulers.io())
.flatMapSingle(列表->
可流动。从可流动(列表)
.flatmap(项目->
asyncCallForItem(item.id)
.subscribeOn(Schedulers.io())
.doOnSuccess(响应->{
//从原始项复制状态
response.text=item.text;
})
,1)//并发项调用的数量
托利斯先生()
)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(成功列表->{/*更新UI*/},错误->{/*报告错误*/});

flatMap
it

asyncCallForList()
.subscribeOn(Schedulers.io())
.flatMapSingle(列表->
可流动。从可流动(列表)
.flatmap(项目->
asyncCallForItem(item.id)
.subscribeOn(Schedulers.io())
.doOnSuccess(响应->{
//从原始项复制状态
response.text=item.text;
})
,1)//con的数目