3
다음 코드는 파일 다운로드를 나타냅니다. Observable이 처리되면 호출이 취소됩니다. 필자의 경우 Observable은 Fragment의 onDestroy() 메소드에서 처리됩니다 (사실상 파편에 파 일을 다운로드 할 필요가 없기 때문에 Observable은 파기됩니다). 파일의 다운로드 과정에서 취소가 발생할 때마다이 코드는 SocketException과 충돌합니다. 메시지는 "Socket Closed"또는 "Non-socket on Socket operation"일 수 있습니다. 내 질문은 OkHttp를 사용하여 진행중인 다운로드 요청을 올바르게 취소하는 방법입니다.SocketException 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)
RX-Java 또는 RX-안드로이드와 아무 상관이없는 표시된 코드입니다. –
Util.closeQuietly() 메서드의 코드를 첨부 할 수 있습니까? – yosriz
그것은 설계된대로 작동합니다. 통화를 취소하면 스트림에서 예외가 발생합니다. –