okhttp3大文件下载OutOfMemoryError
OutOfMemoryError in okhttp3 large file downloading
我尝试通过 okhttp3 下载 zip 文件(大小 160 Mb)。几秒钟后应用程序崩溃并出现堆栈:
java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:59)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
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)
Caused by: java.lang.OutOfMemoryError: Failed to allocate a 8204 byte allocation with 1688 free bytes and 1688B until OOM
at okio.Segment.(Segment.java:61)
at okio.SegmentPool.take(SegmentPool.java:46)
at okio.Buffer.writableSegment(Buffer.java:1151)
at okio.Okio.read(Okio.java:136)
at okio.AsyncTimeout.read(AsyncTimeout.java:238)
at okio.RealBufferedSource.read(RealBufferedSource.java:45)
at okhttp3.internal.http.Http1xStream$FixedLengthSource.read(Http1xStream.java:377)
at okio.RealBufferedSource.request(RealBufferedSource.java:66)
at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:238)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:170)
at okhttp3.RealCall.execute(RealCall.java:60)
at com.bvs.data.MapService.call(MapService.java:102)
at com.bvs.data.MapService.call(MapService.java:94)
at rx.Observable.unsafeSubscribe(Observable.java:10142)
这是我的代码:
Observable.create((Observable.OnSubscribe<ResponseBody>) subscriber -> {
Timber.e("Start zip loading");
Request request = new Request.Builder()
.url(Tweakables.DEV_API_ENDPOINT + "files/" + Tweakables.MAP_ZIP)
.build();
try {
Response response = client.newCall(request).execute(); // Crash appeared at this line
subscriber.onNext(response.body());
response.close();
} catch (IOException e) {
subscriber.onError(e);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<ResponseBody>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
}
@Override
public void onNext(ResponseBody responseBody) {
}
});
也许会对某人有所帮助。使用 Retrofit
注释 Streaming
解决了问题
@Streaming
@GET("files/"+Tweakables.MAP_ZIP)
Call<ResponseBody> downloadMap();
我尝试通过 okhttp3 下载 zip 文件(大小 160 Mb)。几秒钟后应用程序崩溃并出现堆栈:
java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread. at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:59) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272) 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) Caused by: java.lang.OutOfMemoryError: Failed to allocate a 8204 byte allocation with 1688 free bytes and 1688B until OOM at okio.Segment.(Segment.java:61) at okio.SegmentPool.take(SegmentPool.java:46) at okio.Buffer.writableSegment(Buffer.java:1151) at okio.Okio.read(Okio.java:136) at okio.AsyncTimeout.read(AsyncTimeout.java:238) at okio.RealBufferedSource.read(RealBufferedSource.java:45) at okhttp3.internal.http.Http1xStream$FixedLengthSource.read(Http1xStream.java:377) at okio.RealBufferedSource.request(RealBufferedSource.java:66) at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:238) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:170) at okhttp3.RealCall.execute(RealCall.java:60) at com.bvs.data.MapService.call(MapService.java:102) at com.bvs.data.MapService.call(MapService.java:94) at rx.Observable.unsafeSubscribe(Observable.java:10142)
这是我的代码:
Observable.create((Observable.OnSubscribe<ResponseBody>) subscriber -> {
Timber.e("Start zip loading");
Request request = new Request.Builder()
.url(Tweakables.DEV_API_ENDPOINT + "files/" + Tweakables.MAP_ZIP)
.build();
try {
Response response = client.newCall(request).execute(); // Crash appeared at this line
subscriber.onNext(response.body());
response.close();
} catch (IOException e) {
subscriber.onError(e);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<ResponseBody>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
}
@Override
public void onNext(ResponseBody responseBody) {
}
});
也许会对某人有所帮助。使用 Retrofit
注释 Streaming
@Streaming
@GET("files/"+Tweakables.MAP_ZIP)
Call<ResponseBody> downloadMap();