2015-11-12 2 views
4

У меня есть приложение для просмотра pdf, где мне нужно загрузить большие pdf-файлы (например, 136mb). Для этого процесса я использую retrofit2-beta2. Проблема в том, что у меня всегда заканчивается память. Как я могу уточнить, что я загружу большой файл, просто дайте мне byteStream?Из памяти с использованием Retrofit 2 для загрузки файла

Мой интерфейса:

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

У меня есть класс ProgressResponseBody который расширяющий ResponseBody и я установив progressListener здесь, чтобы иметь возможность обновить свой прогрессбар,

и в onResponse функция я просто получить InputStream, как

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

Я добавил @Stream к интерфейсу, но теперь я получаю NetworkOnMainThreadException в ProgressResponseBody.java Ошибка вызывается в super.read (sink, byteCount); ряд. Как я могу поместить это в отдельный поток?

@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; 
      } 
     }; 
    } 

ответ

3

Добавить @Streaming аннотацию на ваш призыв, чтобы получить сырье ResponseBody обратно.

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

Я уже пробовал это, я получал исключение NetworkOnMainThread ... но этот вызов должен быть assync, не так ли? – MegaX

+0

Это потому, что 'response.body()' является сетевым вызовом при использовании '@ Streaming', поэтому теперь вам нужно снять его с основного потока. Для обычного вызова, модернизация делает это для вас. Переместите обработку тела ответа на новый поток (через AsyncTask или аналогичный) – iagreen

+0

не очень хорошо, я сделал это, но не помог ... Я обновил вопрос – MegaX

Смежные вопросы