【问题标题】:OutOfMemoryError in okhttp3 large file downloadingokhttp3 大文件下载中的 OutOfMemoryError
【发布时间】:2017-08-14 11:20:12
【问题描述】:

我正在尝试通过 okhttp3 下载 zip 文件(大小 160 Mb)。几秒钟后应用程序与堆栈崩溃:

java.lang.IllegalStateException:在 Scheduler.Worker 线程上抛出致命异常。 在 rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:59) 在 java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428) 在 java.util.concurrent.FutureTask.run(FutureTask.java:237) 在 java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 在 java.lang.Thread.run(Thread.java:761) 原因:java.lang.OutOfMemoryError:无法分配 8204 字节分配,1688 个空闲字节和 1688B 直到 OOM 在 okio.Segment.(Segment.java:61) 在 okio.SegmentPool.take(SegmentPool.java:46) 在 okio.Buffer.writableSegment(Buffer.java:1151) 在 okio.Okio$2.read(Okio.java:136) 在 okio.AsyncTimeout$2.read(AsyncTimeout.java:238) 在 okio.RealBufferedSource.read(RealBufferedSource.java:45) 在 okhttp3.internal.http.Http1xStream$FixedLengthSource.read(Http1xStream.java:377) 在 okio.RealBufferedSource.request(RealBufferedSource.java:66) 在 okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:238) 在 okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) 在 okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) 在 okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:170) 在 okhttp3.RealCall.execute(RealCall.java:60) 在 com.bvs.data.MapService$2.call(MapService.java:102) 在 com.bvs.data.MapService$2.call(MapService.java:94) 在 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) {

                }
            });

【问题讨论】:

  • 使用下载管理器下载zip等大文件。
  • 可能是HttpLoggingInterceptor 尝试记录响应正文,从而将其内容加载到内存中。
  • @miensol 我尝试设置HttpLoggingInterceptor.Level.NONE同样的错误

标签: android rx-java okhttp3


【解决方案1】:

也许会对某人有所帮助。使用Retrofit注解Streaming解决问题

@Streaming
@GET("files/"+Tweakables.MAP_ZIP)
Call<ResponseBody> downloadMap();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-28
    • 2018-12-22
    • 2010-10-05
    • 2019-12-20
    • 2021-11-07
    • 2023-03-30
    相关资源
    最近更新 更多