以前在我的应用中,我按顺序进行了两次API调用:isCategoryPromoted
和loadCategoryServices
。
我将RxJava2添加到项目中,以便请求可以并行完成。下面的代码总结了实现:
public class ServicesListViewModel{
public final ObservableBoolean loading = new ObservableBoolean();
public final ObservableField<String> loadServicesError = new ObservableField<>();
public void start() {
loading.set(true);
final long categoryId = category.getCategoryId();
final Disposable disposable = Flowable.combineLatest(
categoriesRepository.isPromotedCategory(categoryId),
categoriesRepository.loadServices(categoryId),
(isPromoted, services) -> {
//..processing
}
).doOnError(t -> {
loading.set(false);
loadServicesError.set(t.getMessage());
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
compositeDisposable.add(disposable);
}
}
,
public class ServicesListActivity extends BaseActivity{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//inject viewmodel
setupView();
bindView();
viewModel.start();
}
private void bindView() {
loadingObserver = new Observable.OnPropertyChangedCallback() {
@Override
public void onPropertyChanged(Observable sender, int propertyId) {
if (viewModel.loading.get()) {
showProgressDialog();
} else {
hideProgressDialog();
}
binding.btnNext.setEnabled(!viewModel.loading.get());
}
};
viewModel.loading.addOnPropertyChangedCallback(loadingObserver);
loadServicesErrorObserver = new Observable.OnPropertyChangedCallback() {
@Override
public void onPropertyChanged(Observable sender, int propertyId) {
showErrorDialog(viewModel.loadServicesError.get(), FINISH_ON_CLICK, false);
}
};
viewModel.loadServicesError.addOnPropertyChangedCallback(loadServicesErrorObserver);
}
}
当请求超时时,loadServicesError
被设置,showErrorDialog
中的代码成功执行。但是,在显示错误对话框之前,应用程序崩溃了。 LogCat中出现以下跟踪:
java.net.SocketTimeoutException:无法连接到my.api.com/ (端口443)在10000000ms之后从/192.168.0.10(端口49969): isConnected失败:ETIMEDOUT(连接超时) 在libcore.io.IoBridge.isConnected(IoBridge.java:271) 在libcore.io.IoBridge.connectErrno(IoBridge.java:188) 在libcore.io.IoBridge.connect(IoBridge.java:130) //..truncated .. 在com.myapp.networking.ApiFactory $ 2.intercept(ApiFactory.java:166) //..truncated ..引起:android.system.ErrnoException:isConnected失败:ETIMEDOUT(连接超时) 在libcore.io.IoBridge.isConnected(IoBridge.java:262)... 37更多强制完成活动ServicesListActivity
stacktrace包含以下行:com.myapp.networking.ApiFactory$2.intercept(ApiFactory.java:166)
这是我拦截包含授权令牌的请求的地方:
builder.interceptors().add(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
final Request original = chain.request();
Request.Builder newBuilder = original.newBuilder()
newBuilder.addHeader("Authorization",apiDelegate.getAccessToken());
return chain.proceed(request);//line in stack-tract
}
});
我的问题是:如何处理此异常?
似乎系统决定需要完成Activity,因为请求超时。
在添加RxJava2之前,相同的代码工作正常,所以我很确定问题不在上面发布的代码之外。
我已经浏览了StackOverflow,似乎几乎所有的问题都表明只是增加了会话超时时间。我相信这是一个黑客攻击,应该有一个非常明智的方法来解决这个问题。
更新
CategoriesRepository.kt
override fun isPromotedCategory(categoryId: Long): Flowable<Boolean> = localSource.isPromotedCategory(categoryId)
override fun loadCategoryServices(categoryId: Long): Flowable<CategoryQuestions>
= remoteSource.loadCategoryServices(categoryId)
CategoriesLocalDatsSource.kt
override fun isPromotedCategory(categoryId: Long): Flowable<Boolean> {
return Flowable.create<Boolean>({ subscriber ->
val isPromotedCategory = dbHelper.promotedCategoryDao.idExists(categoryId)
subscriber.onNext(isPromotedCategory)
subscriber.onComplete()
}, BackpressureStrategy.BUFFER)
}
CategoriesRemoteDataSource.kt
override fun loadCategoryServices(categoryId: Long): Flowable<CategoryServices> {
return Flowable.create<CategoryServices>({
service().loadCategoryServices(categoryId)
.enqueue(object : ApiCallback<CategoryServices>() {
override fun success(services: CategoryServices?, response: Response<*>?) {
it.onNext(services)
it.onComplete()
}
override fun failure(throwable: Throwable?) {
it.onError(throwable)
}
})
}, BackpressureStrategy.BUFFER)
}
答案 0 :(得分:1)
正如@Bob Dalgleish所说onError并没有按照你的预期做到。
subscribe()
有多个参数可用于反映结果,第二个参数是您认为的“onError”。请记住,异常是流终端事件,这意味着流在异常后变得不可用,除非您添加错误处理运算符,例如onErrorReturn()