3
次のコードは、ファイルのダウンロードを表しています。 Observableが破棄されると、そのコールはキャンセルされます。私の場合、ObservableはFragmentのonDestroy()メソッドに置かれます(実際には破棄されている、または破棄されるフラグメント上でファイルをダウンロードする必要はないためです)。ファイルのダウンロードプロセス中にキャンセルのシナリオが発生するたびに、このコードはSocketExceptionでクラッシュします。メッセージは、「ソケットクローズ」または「ソケット以外のソケット操作」のいずれかです。私の質問は、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();
}
}
});
}
コンソール:あなたが破壊された断片化しながら、すでに退会している人からエミッタへonError()
を送信しているコード
catch (IOException exception)
{
Log.e("Acme", "onResponse: Exception writing file:", exception);
emitter.onError(exception);
}
で
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
これは設計通りに機能しています。コールをキャンセルすると、ストリームから例外がスローされます。 –