RxJava链请求和更新UI

时间:2016-02-23 12:52:37

标签: android rx-java rx-android

我希望通过RxJavaRetrofit连接三个网络电话。第一个调用(检索会话令牌)必须是第一个,另外两个依赖于此调用,如果第一个调用未完成,则其他两个调用将导致错误。

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

我的第二种方法是平铺请求并使用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()));
                        }

                    }
                });
    }

1 个答案:

答案 0 :(得分:1)

取决于您是希望第二次和第三次呼叫并行执行还是一个接一个地执行。如果同时进行.zip并且不感到沮丧:)

关于您(当前)代码的3个提示(可能您已经知道或者您的应用程序略有不同,所以道歉):

  • 抓住从.subscribe返回的订阅并在onDestroy上杀死(取消订阅)最新的订阅。如果应用关闭,网络通话将继续有效。
  • 如果.requestCurrentPlmn()在一个帖子中,那么.setText会从非ui线程异常的触摸视图中抱怨。
  • 您错过了.subscribe中的.onError。如果请求失败,应用程序将崩溃。