RxJava 链请求和更新 UI
RxJava chain requests and update UI
我想用 RxJava
和 Retrofit
链接三个网络调用。第一个调用(检索会话令牌)必须是第一个,其他两个调用取决于此调用,如果第一个调用之前未完成,其他两个调用将导致错误。
对于另外两个调用,他们应该检索一些信息并更新 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
。如果请求失败,应用程序将崩溃。
我想用 RxJava
和 Retrofit
链接三个网络调用。第一个调用(检索会话令牌)必须是第一个,其他两个调用取决于此调用,如果第一个调用之前未完成,其他两个调用将导致错误。
对于另外两个调用,他们应该检索一些信息并更新 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
。如果请求失败,应用程序将崩溃。