RxJava 链请求和更新 UI

RxJava chain requests and update UI

我想用 RxJavaRetrofit 链接三个网络调用。第一个调用(检索会话令牌)必须是第一个,其他两个调用取决于此调用,如果第一个调用之前未完成,其他两个调用将导致错误。

对于另外两个调用,他们应该检索一些信息并更新 UI。最好的方法是什么? 我首先考虑使用 zip Operator,但我不确定它是否尊重请求的顺序,因为它 returns 是一个值,感觉就像滥用它来捆绑没有任何进一步处理的请求。

我的第二种方法是平面映射请求并使用 doOnNext 更新一次 UI,但我不确定这是否是正确的方法。

private void setUpInitialUIState() {
        restClient.requestSessionToken()
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
                .flatMap(new Func1<SessionTokenResponse, Observable<CurrentPlmnResponse>>() {
                    @Override
                    public Observable<CurrentPlmnResponse> call(SessionTokenResponse sessionTokenResponse) {
                        return restClient.requestCurrentPlmn();
                    }
                })
                .doOnNext(new Action1<CurrentPlmnResponse>() {
                    @Override
                    public void call(CurrentPlmnResponse currentPlmnResponse) {
                        if (!currentPlmnResponse.isError()) {
                            tvProvider.setText(currentPlmnResponse.getData().getFullName());
                        }
                    }
                })
                .flatMap(new Func1<CurrentPlmnResponse, Observable<MonitoringStatusResponse>>() {
                    @Override
                    public Observable<MonitoringStatusResponse> call(CurrentPlmnResponse currentPlmnResponse) {
                        return restClient.requestMonitoringStatus();
                    }
                })
                .subscribe(new Subscriber<MonitoringStatusResponse>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(Throwable throwable) {
                     Log.d("onError", throwable.toString());
                    }

                    @Override
                    public void onNext(MonitoringStatusResponse monitoringStatusResponse) {
                        if (monitoringStatusResponse != null && !monitoringStatusResponse.isError() && monitoringStatusResponse.getData().getSignalIcon() >= 0 && monitoringStatusResponse.getData().getSignalIcon() <= 5) {
                            ivSignalStrength.setImageResource(getResources().getIdentifier("ic_signal_" + monitoringStatusResponse.getData().getSignalIcon(), "drawable", getPackageName()));
                            tvNetworkType.setText(getNetworkTypeTitle(monitoringStatusResponse.getData().getCurrentNetworkType()));
                        }

                    }
                });
    }

取决于您希望第 2 次和第 3 次调用并行执行还是一个接一个执行。如果并行去 .zip 并且不要为此感到难过:)

关于您的(当前)代码的 3 条提示(也许您已经意识到您的应用程序有所不同或略有不同,所以抱歉):

  • 捕获从 .subscribe 返回的订阅并最迟在 onDestroy 处终止(取消订阅)。如果应用程序关闭,网络调用将继续存在。
  • 如果 .requestCurrentPlmn() 在一个线程中,那么 .setText 将从非 ui 线程异常的触摸视图中抱怨。
  • 您在 .subscribe 中错过了 .onError。如果请求失败,应用程序将崩溃。