我正在尝试将两个表单插入一个使用RxJava,RxAndroid和Mosby3,但我找不到让它工作的方法。
我的结构:
public final class CheckinIntent {
private final CheckinCommand checkinCommand;
private final Bitmap signature;
public CheckinIntent(CheckinCommand checkinCommand, Bitmap signature) {
this.checkinCommand = checkinCommand;
this.signature = signature;
}
public CheckinCommand getCheckinCommand() {
return checkinCommand;
}
public Bitmap getSignature() {
return signature;
}
}
我解雇我的意图(MVI模式):
final Observable<Bitmap> signatureObservable = Observable.just(BitmapFactory.decodeFile(storage.getFile("signs", booking.getBookingId()).getAbsolutePath()));
final Observable<CheckinCommand> checkinCommandObservable = Observable.just(new CheckinCommand(booking.getBookingId(), booking.getUserId(), booking.getPartnerId(), userDetailsTextView.getText().toString(), "google.com"));
final Observable<CheckinIntent> intentObservable = Observable.zip(signatureObservable, checkinCommandObservable, (image, command) -> new CheckinIntent(command, image));
return saveButtonClickObservable
.flatMap(bla -> intentObservable);
将它们绑定在一起:
@Override
protected void bindIntents() {
Observable<CheckinViewState> checkinViewStateObservable =
intent(CheckinView::sendCheckin)
.flatMap(checkinIntent -> imageRepository.uploadImage(checkinIntent.getSignature())
.flatMap(command -> bookingRepository.doCheckin(command) <------ PROBLEM HERE, HOW CAN I ACCESS THE COMMAND FROM ABOVE ??
.subscribeOn(Schedulers.from(threadExecutor))
.map(CheckinViewState.Success::new)
.cast(CheckinViewState.class)
.startWith(new CheckinViewState.LoadingState())
.onErrorReturn(CheckinViewState.ErrorState::new))
.observeOn(postExecutionThread.getScheduler());
subscribeViewState(checkinViewStateObservable, CheckinView::render);
}
Observable<CnhImageResponse> uploadImage(Bitmap bitmap);
我的问题是,我的uploadImage返回一个以String结尾的内部结构,但是,如何获取返回的字符串,将其添加到我的command
对象(在此对象中设置返回的URL)和继续流程(将我的命令发送到云端)?
谢谢!
答案 0 :(得分:2)
直接在第一个flatMap内的observable上的flatMap。在这种情况下,您可以同时参考checkinIntent和command
wsgi.conf
替代解决方案:将 @Override
protected void bindIntents() {
Observable<CheckinViewState> checkinViewStateObservable =
intent(CheckinView::sendCheckin)
.flatMap(checkinIntent -> {
return imageRepository.uploadImage(checkinIntent.getSignature()
.flatMap(imageResponse -> bookingRepository.doCheckin(command) <-- Now you have access to both, command and CnhImageResponse
})
.subscribeOn(Schedulers.from(threadExecutor))
.map(CheckinViewState.Success::new)
.cast(CheckinViewState.class)
.startWith(new CheckinViewState.LoadingState())
.onErrorReturn(CheckinViewState.ErrorState::new))
.observeOn(postExecutionThread.getScheduler());
subscribeViewState(checkinViewStateObservable, CheckinView::render);
}
从Pair<CheckinIntent, Command>
传递给Observable,如下所示:
bookingRepository.doCheckin(...)
其他几点说明:
你几乎想在MVI中更喜欢@Override
protected void bindIntents() {
Observable<CheckinViewState> checkinViewStateObservable =
intent(CheckinView::sendCheckin)
.flatMap(checkinIntent -> imageRepository.uploadImage(checkinIntent.getSignature()
.map(imageResponse -> Pair.create(checkinIntent, imageResponse))) // Returns a Pair<CheckinIntent, CnhImageResponse>
.flatMap(pair -> bookingRepository.doCheckin(pair.first) <-- Now you can access the pair holding both information
.subscribeOn(Schedulers.from(threadExecutor))
.map(CheckinViewState.Success::new)
.cast(CheckinViewState.class)
.startWith(new CheckinViewState.LoadingState())
.onErrorReturn(CheckinViewState.ErrorState::new))
.observeOn(postExecutionThread.getScheduler());
subscribeViewState(checkinViewStateObservable, CheckinView::render);
}
而不是switchMap()
。 switchMap取消订阅以前的订阅,而flatMap不是。这意味着,如果你像你在代码中所做的那样pingMap并且无论出于何种原因新的checkinIntent被触发而旧的还没有完成(即imageRepository.uploadImage()仍在进行中)你最终会有两个流这将调用flatMap()
因为第一个仍然继续工作并通过您建立的可观察流发出结果。 switchMap()通过在开始“switchMaping”新意图之前取消订阅第一个(未完成的)意图来防止这种情况,这样你当时只有1个流。
您构建CheckinView::render
的方式应移至演示者。这对于“转储”视图来说太过“逻辑”了。另外CheckinIntent
正在主线程上运行。我建议使用Observable.just(BitmapFactory.decodeFile(...))
作为后者推迟他的“工作”(位图解码)直到这个observable实际订阅,然后你可以应用后台调度程序。 Observable.just()基本上与:
Observable.fromCallable( () -> BitmapFactory.decodeFile(...))