Android 添加RxJava2后,应用程序在SocketTimeout上崩溃

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

以前在我的应用程序中,我按顺序进行了两次API调用:
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
,它在Flowables
onError
中处理。我唯一不明白的是为什么Android系统决定让应用程序崩溃。链接回我的代码的唯一例外是
intercept()
方法订阅中没有实际的错误处理程序。虽然
doError()
可以报告错误,但它不是实际的处理程序。更改
subscribe()
以使用观察者或添加处理程序。