Android 改装2+;RxJava将相似的请求干净地链接在一起

Android 改装2+;RxJava将相似的请求干净地链接在一起,android,rest,rx-java,retrofit2,Android,Rest,Rx Java,Retrofit2,目标 在我的应用程序中,我希望使用Reformation 2将一些文件上载到我的web服务器(在本例中为图片),并且在完成每个文件的上载后,我希望使用该特定文件的路径更新SQL表 尝试过 我对使用函数式编程范例还不熟悉,所以我的理解可能会被误导。我有两个不同的对象,一个文件响应(DTO表示上传文件后web服务器的响应)和一个照片对象。此照片对象有两个字段,充当在后端服务器中持久化的实体。它的字段对应于列,并且单独上传每个对象都可以。我试着在一次扫描中完成这个双重操作 以下是我尝试过的: List

目标

在我的应用程序中,我希望使用Reformation 2将一些文件上载到我的web服务器(在本例中为图片),并且在完成每个文件的上载后,我希望使用该特定文件的路径更新SQL表

尝试过

我对使用函数式编程范例还不熟悉,所以我的理解可能会被误导。我有两个不同的对象,一个文件响应(DTO表示上传文件后web服务器的响应)和一个照片对象。此照片对象有两个字段,充当在后端服务器中持久化的实体。它的字段对应于列,并且单独上传每个对象都可以。我试着在一次扫描中完成这个双重操作

以下是我尝试过的:

List<Observable<FileResponse>> mObservables = new ArrayList<>(3);

...
...

Observable.merge(mObservables).
            map(new Func1<FileResponse, Observable<Photo>>() {
                @Override
                public Observable<Photo> call(FileResponse fileResponse) {
                    Photo photo = new Photo();
                    photo.setPath(fileResponse.getUrl());
                    photo.setId("demo123");
                    return mPhotoService.createPhoto(photo);
                }
            }).forEach(
                new Action1<Observable<Photo>>() {
                    @Override
                    public void call(Observable<Photo> photoObservable) {

                    }
                },
                new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        Log.e(TAG, "Error: " + throwable.getMessage());
                    }
                }
            );
List mObservables=newarraylist(3);
...
...
可观察。合并(mObservables)。
映射(新函数1(){
@凌驾
公共可观察调用(FileResponse FileResponse){
照片=新照片();
setPath(fileResponse.getUrl());
照片。setId(“demo123”);
返回mPhotoService.createPhoto(照片);
}
})弗雷奇先生(
新行动1(){
@凌驾
公共无效呼叫(可观察光可观察){
}
},
新行动1(){
@凌驾
公共无效呼叫(可丢弃可丢弃){
Log.e(标记“Error:+throwable.getMessage());
}
}
);
以下是我的逻辑:

合并( ) — 将多个观测值合并为一个。

我希望将我创建的观察对象列表合并在一起,以便对它们中的每一个执行相同的操作。在本例中,观察对象的类型为FileResponse。这是上传到文件web服务的内容

map()-通过对每个项目应用一个函数来转换可观察项目发出的项目。

在本例中,我想对FileResponse Observable应用一个函数,该函数返回一个新的Observable,Observable

forEach( ) — 对可观察对象发出的每个项目调用一个函数;直到可观察对象完成为止。

然后,这将获取每个发出的可观察对象并将其上载。不过,在这种情况下,此部分失败。文件成功上载,但forEach部分仅返回“Error:null”

问题

这种理解是否接近于我试图实现的目标?同样,我只希望将多个请求链接在一起,在其他请求成功时执行新请求。是否有更好/正确的方法来做到这一点

编辑注释:

我忘了提一下,我可以像这样实现我想要的:

Observable.merge(mObservables)
            .map(new Func1<FileResponse, Observable<Photo>>() {
                @Override
                public Observable<Photo> call(FileResponse fileResponse) {
                    Photo photo = new Photo();
                    photo.setPath(fileResponse.getUrl());
                    photo.setDogId("123");
                    return mPhotoService.createPhoto(photo);
                }
            })
           .subscribe(new Subscriber<Observable<Photo>>() {
                    @Override
                    public void onCompleted() {
                        Log.d(TAG, "Save complete!");
                    }

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

                    @Override
                    public void onNext(Observable<Photo> photoObservable) {
                        photoObservable.subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread())
                                .subscribe(new Subscriber<Photo>() {
                                    @Override
                                    public void onCompleted() {
                                        Log.d(TAG, "Here!");
                                    }

                                    @Override
                                    public void onError(Throwable e) {
                                        Log.d(TAG, "Error! " + e.getMessage());
                                    }

                                    @Override
                                    public void onNext(Photo photo) {
                                        Log.d(TAG, "Woo!!");
                                    }
                                });
                    }
                }
            );
Observable.merge(mObservables)
.map(新函数1(){
@凌驾
公共可观察调用(FileResponse FileResponse){
照片=新照片();
setPath(fileResponse.getUrl());
照片:setDogId(“123”);
返回mPhotoService.createPhoto(照片);
}
})
.subscribe(新订户(){
@凌驾
未完成的公共无效(){
Log.d(标记“保存完成!”);
}
@凌驾
公共无效申报人(可丢弃的e){
Log.e(标记“Error:+e.getMessage());
}
@凌驾
public void onNext(可观察到的光可观察到的){
photoObservable.subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread())
.subscribe(新订户(){
@凌驾
未完成的公共无效(){
Log.d(标记“Here!”);
}
@凌驾
公共无效申报人(可丢弃的e){
Log.d(标记“Error!”+e.getMessage());
}
@凌驾
下一页(照片){
Log.d(标记为“Woo!!”);
}
});
}
}
);
但是我试图找到一种可能更干净的方法来做这件事。如果这是唯一的方法,那就足够公平了。我只是想获得更多的意见,看看我能做些什么来让它看起来更好(或最佳实践)。

要使它更干净(并避免额外订阅
onNext
中的项目),你可以切换
map()
适用于:

Observable.merge(mObservables)
.flatMap(新函数1(){
@凌驾
公共可观察调用(FileResponse FileResponse){
照片=新照片();
返回mPhotoService.createPhoto(照片);
}
})
.forEach(新行动1){
@凌驾
公众作废通知(照片){
}
});

正如您在代码段中所看到的,在
flatMap
之后的下一个操作符将看到
Photo
对象(与
Observable
之后的
map()
)。

Nice我喜欢这样。但一个问题是它返回一个