2012-03-19 2 views
2

У меня есть приложение, в котором я пытаюсь загрузить файл. Я использую HTTPUrlConnection для загрузки. Первоначально скорость загрузки была медленной.Android/Java slow network IO

Я улучшил производительность с помощью буферизованного потока ввода и увеличил размер моего буфера с 1024 до 8192. Увеличение буфера за пределами этого не привело к каким-либо улучшениям.

Вот отрывок:

InputStream inputStream = (InputStream) new URL(requestURL) 
        .getContent(); 
BufferedInputStream bufferedInputStream = new BufferedInputStream(
        inputStream); 
OutputStream outputStream = new FileOutputStream(fileSaveUrl); 
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(
        outputStream);  

int bytesToRead = 1024 * 256; 
byte buffer[] = new byte[bytesToRead]; 
while ((count = bufferedInputStream.read(buffer)) != -1 
    && !isCancelled()) { 
     requestStatus((int) (downloaded * 100/fileSize)); 
     bufferedOutputStream.write(buffer, 0, count); 
} 

Даже после этого, те же самые загрузки файлов в 2 раза быстрее на IPad по сравнению с Android.

Я что-то упустил?

редактирует

  1. Даже прежде чем спросить/упоминания, загрузка выполняется в отдельном потоке. Я понимаю, что мне не нужно буфера вывода, но я обойти, что позже :)
  2. О bytesToRead: Я экспериментировал с различными размерами буфера, последний эксперимент был 256Кб
+0

Вы пробовали, сколько ускорений вы получаете, отключив запись данных на диск? – Robert

+0

Я бы, но Android имел ограниченный размер кучи, предоставляемый приложениям, и файлы могли быть больше, чем предоставленный размер кучи, поэтому я прямо пишу его на SD-карту. Кроме того, я выполнил несколько тестов, раздел «Запись в файл» не замедляет работу всей программы. –

+1

«Также я выполнил несколько тестов, раздел« Запись в файл »не замедляет работу всей программы» - так должно быть. Обычно в многопоточном программировании вы пишете в другом потоке, чем вы читаете, если вы нацелены на максимальную производительность. – CommonsWare

ответ

2

Проблема была в том, что я загружал и записывал на SD-карту в той же теме. Разделите работу на два потока, используя буфер очереди блокировки, чтобы повысить производительность.

2
requestStatus((int) (downloaded * 100/fileSize)); 

Это может быть одним из возможных узких мест. Обновление статуса в том же потоке, что и ваша работа, обычно не является хорошей идеей. Ваша нить должна обновлять изменчивую переменную ...

variable = (int) (downloaded * 100/fileSize); 

Тогда ваш поток пользовательского интерфейса должен опросить эту переменную, чтобы показать прогресс.

Кроме того, самые дешевые SD-карты работают медленно, их запись, вероятно, приведет к замедлению работы больших файлов.

+0

Это не шея бутылки, а очень действительная точка :) –