3
以下代碼表示下載文件。當Observable被處置時,該呼叫將被取消。在我的情況下,Observable將被放置在Fragment的onDestroy()方法中(由於事實上它不需要繼續下載已被或將被銷燬的片段上的文件)。每當在文件的下載過程中發生場景取消時,此代碼將以SocketException崩潰。該消息可以是「套接字關閉」或「非套接字上的套接字操作」。我的問題是如何使用OkHttp正確取消正在進行的下載請求?使用OkHttp取消呼叫時的SocketException
代碼:
Request request = //..
final Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException error)
{
Log.e("Acme", "OnFailure:", error);
emitter.onError(error);
}
@Override
public void onResponse(Call call, Response response) throws IOException
{
if (response.isSuccessful())
{
BufferedSink sink = null;
BufferedSource source = null;
try
{
Log.d("Acme", "onResponse: Start writing..");
sink = Okio.buffer(Okio.sink(file));
source = response.body().source();
sink.writeAll(source); // Crash on this line.
sink.flush();
emitter.onNext(file);
emitter.onComplete();
}
catch (IOException exception)
{
Log.e("Acme", "onResponse: Exception writing file:", exception);
emitter.onError(exception);
}
finally
{
Log.d("Acme", "onResponse: Trying to close..");
Util.closeQuietly(sink);
Util.closeQuietly(source);
Log.d("Acme", "onResponse: Closed..");
}
}
}
});
emitter.setCancellable(new Cancellable() {
@Override
public void cancel() throws Exception
{
if (!call.isCanceled())
{
call.cancel();
}
}
});
}
控制檯:
D/Acme: onResponse: Start writing..
E/AndroidRuntime: FATAL EXCEPTION: OkHttp https://acme.nl/...
Process: nl.acme.app.development.debug, PID: 12432
java.net.SocketException: Socket operation on non-socket
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:151)
at java.net.SocketInputStream.read(SocketInputStream.java:120)
at okio.Okio$2.read(Okio.java:138)
at okio.AsyncTimeout$2.read(AsyncTimeout.java:236)
at okio.RealBufferedSource.read(RealBufferedSource.java:45)
at okhttp3.internal.http1.Http1Codec$FixedLengthSource.read(Http1Codec.java:385)
at okio.RealBufferedSource.read(RealBufferedSource.java:45)
at okio.RealBufferedSink.writeAll(RealBufferedSink.java:97)
at nl.app.acme.infrastructure.network.Api$44$1.onResponse(Api.java:3322)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:135)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
顯示的代碼與rx-java或rx-android沒有任何關係。 –
你可以附上Util.closeQuietly()方法的代碼嗎? – yosriz
這是按設計工作。當你取消一個調用時,它的流會拋出異常。 –