Android 添加RxJava2后,应用程序在SocketTimeout上崩溃
以前在我的应用程序中,我按顺序进行了两次API调用:Android 添加RxJava2后,应用程序在SocketTimeout上崩溃,android,retrofit2,rx-java2,Android,Retrofit2,Rx Java2,以前在我的应用程序中,我按顺序进行了两次API调用:isCategoryPromoted和loadCategoryServices 我将RxJava2添加到项目中,以便可以在Parralel中完成请求。以下代码总结了实施情况: public class ServicesListViewModel{ public final ObservableBoolean loading = new ObservableBoolean(); public final ObservableFi
isCategoryPromoted
和loadCategoryServices
我将RxJava2添加到项目中,以便可以在Parralel中完成请求。以下代码总结了实施情况:
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);
}
}
当请求超时时,loadServicesError
被设置,并且对话框中的代码成功执行。但是,就在显示错误对话框之前,应用程序崩溃。以下跟踪显示在LogCat中:
java.net.SocketTimeoutException:无法连接到my.api.com/
1000000ms后从/192.168.0.10(端口49969)开始的(端口443):
断开连接失败:ETIMEDOUT(连接超时)
在libcore.io.IoBridge.isConnected处(IoBridge.java:271)
在libcore.io.IoBridge.ConnecterNo(IoBridge.java:188)中
在libcore.io.IoBridge.connect上(IoBridge.java:130)
//..被截断。。
在com.myapp.networking.ApiFactory$2.intercept(ApiFactory.java:166)上
//..被截断。。原因:android.system.ErrnoException:isConnected失败:ETIMEDOUT(连接超时)
在libcore.io.IoBridge.isConnected(IoBridge.java:262)中。。。37更多强制完成活动服务持续性
stacktrace包括以下行:com.myapp.networking.apifacture$2.intercept(apifacture.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
}
});
我的问题是:我如何处理这个异常
似乎是因为请求超时,系统决定需要完成活动
在添加RxJava2之前,相同的代码工作得很好,因此我相当确定问题不在上面发布的代码之外
我已经经历了StackOverflow,几乎所有的问题都建议只增加会话超时时间。我认为这是一种黑客行为,应该有一种完全明智的方法来解决这个问题
更新
CategoriesRepository.kt
override fun isPromotedCategory(categoryId: Long): Flowable<Boolean> = localSource.isPromotedCategory(categoryId)
override fun loadCategoryServices(categoryId: Long): Flowable<CategoryQuestions>
= remoteSource.loadCategoryServices(categoryId)
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)
}
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)
}
isPromotedCategory(categoryId:Long):Flowable=localSource.isPromotedCategory(categoryId)
覆盖有趣的loadCategoryServices(categoryId:Long):可流动
=remoteSource.loadCategoryServices(categoryId)
分类LocalDatsSource.kt
override fun isPromotedCategory(categoryId: Long): Flowable<Boolean> = localSource.isPromotedCategory(categoryId)
override fun loadCategoryServices(categoryId: Long): Flowable<CategoryQuestions>
= remoteSource.loadCategoryServices(categoryId)
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)
}
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)
}
isPromotedCategory(categoryId:Long):可流动{
返回可流动的。创建({subscriber->
val isPromotedCategory=dbHelper.promotedCategoryDao.idExists(categoryId)
subscriber.onNext(iPromotedCategory)
subscriber.onComplete()
},背压等级。缓冲器)
}
分类删除数据源.kt
override fun isPromotedCategory(categoryId: Long): Flowable<Boolean> = localSource.isPromotedCategory(categoryId)
override fun loadCategoryServices(categoryId: Long): Flowable<CategoryQuestions>
= remoteSource.loadCategoryServices(categoryId)
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)
}
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)
}
override fun loadCategoryServices(categoryId:Long):可流动{
return-Flowable.create({
服务().loadCategoryServices(categoryId)
.enqueue(对象:ApiCallback(){
覆盖乐趣成功(服务:类别服务?,响应:响应?){
it.onNext(服务)
it.onComplete()
}
覆盖乐趣失败(可丢弃:可丢弃?){
it.onError(可丢弃)
}
})
},背压等级。缓冲器)
}
正如@Bob Dalgleish所说,OneRor并没有做你所期望的事情。
<代码>订阅()/代码>有多个参数可以用来反映结果,第二个参数是您所考虑的“OnError”。请记住,异常是流终端事件,这意味着流在发生异常后将变得不可用,除非您添加错误处理操作符,如onerrorreet()
,堆栈跟踪显示它在10000秒后超时,因此,如您所说,增加超时将没有帮助。因此,您在isCategoryPromoted()
或loadCategoryServices()
中有一个错误,您都没有提供这两个错误。由于这些方法没有在以前的代码中使用,它们很可能是罪魁祸首。@BobDalgleish这些方法在以前版本的代码中使用过,但是它们使用回调而不是返回“Flowable”。我怀疑它们可能是问题的原因,但是调试表明它们执行时没有错误。我将在稍后介绍他们的源代码我们的网络代码超时了,您不确定哪个网络呼叫正在超时?请求是通过电话发出的吗?你有什么样的测试工具?我知道哪个请求超时了。它是loadCategoryServices
。这个请求确实是通过电话发出的。我确实得到了一个SocketTimeoutException
,它在FlowablesonError
中处理。我唯一不明白的是为什么Android系统决定让应用程序崩溃。链接回我的代码的唯一例外是intercept()
方法订阅中没有实际的错误处理程序。虽然doError()
可以报告错误,但它不是实际的处理程序。更改subscribe()
以使用观察者或添加处理程序。