Следующий код представляет загрузку файла. Вызов будет отменен, когда Observable будет удален. В моем случае Observable будет размещен в методе onDestroy() Фрагмента (поскольку ему не нужно будет продолжать загрузку файла на Фрагменте, который уничтожен или будет уничтожен). Всякий раз, когда происходит сценарий отмены во время процесса загрузки файла, этот код аварийно завершает работу с SocketException. Сообщение может быть либо "Socket Closed", либо "Socket Operation on non-socket". Мой вопрос: как правильно отменить текущий запрос на загрузку с помощью OkHttp?
Код:
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)