结合以前的观察结果

时间:2017-06-14 20:56:35

标签: java android rx-java2 mosby

我正在尝试将两个表单插入一个使用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)和继续流程(将我的命令发送到云端)?

谢谢!

1 个答案:

答案 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(...))