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;
}
};
}
Add the @Streaming
annotation to your call to get the raw ResponseBody
back.
@Streaming
@GET("url")
Call<ResponseBody> getData(params);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With