Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Out of Memory using Retrofit 2 for downloading a file

I have a pdf viewer app where I have to download big pdf files (136mb for example) I am using retrofit2-beta2 for this process. The problem is that I am always running out of memory. How can I tell retrofit that I will download a big file please just give the byteStream to me?

My interface is:

@GET("url")
Call<ResponseBody> getData(params);

I have a ProgressResponseBody class which is extending the ResponseBody and I am setting a progressListener here, to be able to refresh my progressbar,

and in the onResponse function I just get the InputStream like

InputStream input = response.body().byteStream();
FileOutputStream out = new FileOutputStream(file);
int bufferSize=1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while (len = input.read(buffer) != -1) {
    out.write(buffer,0,len);
} 
if(out!=null)
    out.close();

UPDATE

I have added the @Stream to the interface but now i get NetworkOnMainThreadException in the ProgressResponseBody.java The error is thrown in the super.read(sink,byteCount); row. How could I put this to a separate thread?

@Override
    public BufferedSource source() throws IOException {
        if (bufferedSource == null) {
            bufferedSource = Okio.buffer(source(responseBody.source()));
        }
        return bufferedSource;
    }

    private Source source(Source source) {
        return new ForwardingSource(source) {
            long totalBytesRead = 0L;

            @Override
            public long read(Buffer sink, long byteCount) throws IOException {
                long bytesRead = super.read(sink, byteCount);
                totalBytesRead += bytesRead != -1 ? bytesRead : 0;
                progressListener.update(totalBytesRead, responseBody.contentLength(), bytesRead == -1);
                return bytesRead;
            }
        };
    }
like image 592
MegaX Avatar asked Nov 12 '15 00:11

MegaX


1 Answers

Add the @Streaming annotation to your call to get the raw ResponseBody back.

@Streaming
@GET("url")
Call<ResponseBody> getData(params);
like image 101
iagreen Avatar answered Sep 23 '22 20:09

iagreen