我正在使用以下(过时的)库:
Retrofit: 1.9.0
OkHTTP: 2.3.0
RxAndroid: 0.24.0
我注意到,每隔一段时间我就会收到以下 POST 请求的堆栈跟踪:
D/Retrofit: ---> HTTP POST https:xxxxx
D/Retrofit: Content-Type: application/x-www-form-urlencoded; charset=UTF-8
D/Retrofit: Content-Length: 396
D/Retrofit: ---> END HTTP (396-byte body)
D/Retrofit: ---- ERROR https:xxxxx
I/Choreographer: Skipped 33 frames! The application may be doing too much work on its main thread.
D/Retrofit: java.io.InterruptedIOException
at okio.Timeout.throwIfReached(Timeout.java:146)
at okio.Okio$1.write(Okio.java:75)
at okio.AsyncTimeout$1.write(AsyncTimeout.java:155)
at okio.RealBufferedSink.flush(RealBufferedSink.java:201)
at com.squareup.okhttp.internal.http.HttpConnection.flush(HttpConnection.java:140)
at com.squareup.okhttp.Connection.makeTunnel(Connection.java:399)
at com.squareup.okhttp.Connection.upgradeToTls(Connection.java:229)
at com.squareup.okhttp.Connection.connect(Connection.java:159)
at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:175)
at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:120)
at com.squareup.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:330)
at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:319)
at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:241)
at com.squareup.okhttp.Call.getResponse(Call.java:271)
at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:228)
at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:199)
at com.squareup.okhttp.Call.execute(Call.java:79)
at retrofit.client.OkClient.execute(OkClient.java:53)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:240)
at java.lang.reflect.Proxy.invoke(Proxy.java:913)
at $Proxy1.replyTransaction(Unknown Source)
< App Specific Trace >
at rx.Observable$1.call(Observable.java:145)
at rx.Observable$1.call(Observable.java:137)
at rx.Observable.unsafeSubscribe(Observable.java:7304)
at rx.internal.operators.OperatorSubscribeOn$1$1.call(OperatorSubscribeOn.java:62)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:47)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:457)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
D/Retrofit: ---- END ERROR
retrofit.RetrofitError
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:395)
at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:240)
at java.lang.reflect.Proxy.invoke(Proxy.java:913)
at $Proxy1.replyTransaction(Unknown Source)
< App Specific Trace >
at rx.Observable$1.call(Observable.java:145)
at rx.Observable$1.call(Observable.java:137)
at rx.Observable.unsafeSubscribe(Observable.java:7304)
at rx.internal.operators.OperatorSubscribeOn$1$1.call(OperatorSubscribeOn.java:62)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:47)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:457)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.io.InterruptedIOException
at okio.Timeout.throwIfReached(Timeout.java:146)
at okio.Okio$1.write(Okio.java:75)
at okio.AsyncTimeout$1.write(AsyncTimeout.java:155)
at okio.RealBufferedSink.flush(RealBufferedSink.java:201)
at com.squareup.okhttp.internal.http.HttpConnection.flush(HttpConnection.java:140)
at com.squareup.okhttp.Connection.makeTunnel(Connection.java:399)
at com.squareup.okhttp.Connection.upgradeToTls(Connection.java:229)
at com.squareup.okhttp.Connection.connect(Connection.java:159)
at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:175)
at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:120)
at com.squareup.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:330)
at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:319)
at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:241)
at com.squareup.okhttp.Call.getResponse(Call.java:271)
at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:228)
at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:199)
at com.squareup.okhttp.Call.execute(Call.java:79)
at retrofit.client.OkClient.execute(OkClient.java:53)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:240)
at java.lang.reflect.Proxy.invoke(Proxy.java:913)
at $Proxy1.replyTransaction(Unknown Source)
< App Specific Trace >
at rx.Observable$1.call(Observable.java:145)
at rx.Observable$1.call(Observable.java:137)
at rx.Observable.unsafeSubscribe(Observable.java:7304)
at rx.internal.operators.OperatorSubscribeOn$1$1.call(OperatorSubscribeOn.java:62)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:47)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:457)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
我的代码如下:
网络调用:
return Observable.create(new Observable.OnSubscribe<Object>() {
@Override public void call(Subscriber<? super Object> subscriber) {
try {
subscriber.onNext(/* Sync network call here. */);
} catch (Exception e) {
subscriber.onError(e);
}
subscriber.onCompleted();
}
})
.onBackpressureBuffer()
// singleton for Schedulers.io()
.subscribeOn(ioScheduler)
// singleton for AndroidSchedulers.mainThread()
.observeOn(mainThreadScheduler);
其名称如下:
subscription = makeNetworkCall()
.subscribe(new Observer<Object>() {
@Override public void onNext(Object object) {
// close and finish activity
}
@Override public void onError(Throwable e) {
// whoops!
}
});
并在 Activity 中取消订阅,如下所示:
@Override
protected void onPause() {
super.onPause();
if (subscription != null) {
subscription.unsubscribe();
subscription = null;
if (condition) {
finish();
}
}
}
我对此的理解是,我收到 InterruptedException
因为我在 onPause 中从
。不过,我们会针对其他请求执行此操作,因此我不确定为什么我只在这里看到它以及到底为什么会发生这种情况。Subscription
中 unsubscribe()
()
为了提供更多相关信息,网络调用是通过通知操作从锁定屏幕启动的 Activity 进行的,以强制用户解锁其设备以便采取操作。
我的问题是为什么会发生这种情况,有没有好的方法可以解决这个问题?根据一些文章,您应该在 onPause()
取消订阅 Observables
。
更多信息可以参见 In okHTTP's github issues
谢谢!
最佳答案
这是一个猜测,但可能是您在发出中断异常之前没有检查订阅者是否仍然存在。
试试这个:
return Observable.create(new Observable.OnSubscribe<Object>() {
@Override public void call(Subscriber<? super Object> subscriber) {
try {
subscriber.onNext(/* Sync network call here. */);
subscriber.onCompleted();
} catch (Exception e) {
if (!subscriber.isUnsubscribed()) { // <-- check before emitting error
subscriber.onError(e);
}
}
}
})
关于android - Retrofit/OkHTTP/RxJava 间歇性 InterruptedIOException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48068595/