2017-10-19 257 views
-1

我有一个使用sdk版本25开发的Android项目。我使用RXJava作为我的线程管理和Retrofit库来打网络。SocketTimeoutException由RxJava未处理

我还实现了用于添加重写有趣拦截(链:Interceptor.Chain)的自定义拦截器:响应? {

val request = addHeader(chain) 

    val response = chain.proceed(request) 
    checkErrorResponse(response) 

    return response 

api调用将始终在RX Java流程内,我正在确保它。将我的APK放到Playstore后,Crashlytics检测到崩溃。

#0. Crashed: main: 0 0 0x0000000000000000 
    at okio.Okio$4.newTimeoutException(Okio.java:230) 
    at okio.AsyncTimeout.exit(AsyncTimeout.java:285) 
    at okio.AsyncTimeout$2.read(AsyncTimeout.java:241) 
    at okio.RealBufferedSource.indexOf(RealBufferedSource.java:345) 
    at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:217) 
    at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:211) 
    at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:189) 
    at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:75) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
    at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
    at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
    at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
    at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
    at com.payfazz.data.base.net.PayfazzInterceptor.intercept(PayfazzInterceptor.kt:24) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185) 
    at okhttp3.RealCall.execute(RealCall.java:69) 
    at retrofit2.OkHttpCall.execute(OkHttpCall.java:180) 
    at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:41) 
    at io.reactivex.Observable.subscribe(Observable.java:10842) 
    at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:33) 
    at io.reactivex.Observable.subscribe(Observable.java:10842) 
    at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:33) 
    at io.reactivex.Observable.subscribe(Observable.java:10842) 
    at io.reactivex.internal.operators.observable.ObservableDefer.subscribeActual(ObservableDefer.java:39) 
    at io.reactivex.Observable.subscribe(Observable.java:10842) 
    at io.reactivex.internal.operators.observable.ObservableDefer.subscribeActual(ObservableDefer.java:39) 
    at io.reactivex.Observable.subscribe(Observable.java:10842) 
    at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96) 
    at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker$BooleanRunnable.run(ExecutorScheduler.java:260) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
    at java.lang.Thread.run(Thread.java:818) 

当我调查stacktrace时,发现我的代码恰好在我的自定义拦截器中。据我所知,崩溃是由SocketTimeoutException造成的,然后是超时请求。然后我尝试重现超时但不能完成。在我的环境中,异常总是被RX Java捕获并发送到onError()方法。

RX Java如何不能捕捉到崩溃?为了安全起见,我应该使用catch块来包装proceed()方法吗?

+0

您是否找到了解决方法?我遇到同样的问题,它正在崩溃我的应用程序。 – dazza5000

回答

0

这些类型的崩溃是在RxJava生命周期之外抛出异常时引起的。这意味着你的异常可以通过这两个选项之一造成的:

  1. retrofit sourcecode去,因此可能会出现Disposable.dispose()被称为竞态条件,但潜在的Call被取消之前发生超时。这会导致超时被发送给观察者后,它已被disposed,触发崩溃。
  2. onError处理程序中抛出错误。这不应该根据RxJava协议发生,并会导致与CompositeException崩溃。由于您发布的错误不包括确切的Exception类,因此不能排除。
+0

以及我认为第一个问题是,如果在'onError'方法内发生崩溃,堆栈应该显示'onError'方法内的代码引起的错误。我一定会知道的。关于第一个,你有什么建议来防止它? –

+0

像这样的问题很难解决。在Interceptor中为特定异常添加try-catch可能会暂时解决您的问题,但也可能捕获应该通过observable的异常。我建议在改进github上打开一个问题,以链接到这个问题,这样可以解决潜在的问题。 或者,你可以为RxJava的全局异常处理程序创建一个包装器,以过滤掉这个特定的情况,直到它被修复。请参阅'RxJavaPlugins.setErrorHandler' – Kiskae