2016-03-07 2 views
2

У меня есть активность, в которой пользователь нажимает кнопку, которая извлекает ответ JSON из URL-адреса, а затем загружает и сохраняет все URL-адреса изображений в этом JSON. Загрузка происходит в отдельном классе, который простирается Thread:Большой объем памяти выделяется при загрузке изображений с URL-адреса

downloadButton.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     DownloadTask task = new DownloadTask(handler); 
     task.start(); 
    } 
}); 

handler является внутренним статическим Handler, который содержит WeakReference к деятельности (используется для отображения прогресса).

В DownloadTask:

public DownloadTask(Handler handler) { 
    this.handler = handler; 
} 

@Override 
public void run() { 
    String jsonString = // gets JSON from server 

    urlsToDownload = new HashSet<String>(); 

    // do some stuff with the JSON to put each URL into the Set 

    for (Iterator<String> i = urlsToDownload.iterator(); i.hasNext();) { 
     String urlString = i.next(); 

     // the following takes place in two static method calls, 
     // but I've laid it all out here for easier interpretation. 
     // I'm also removing all try/catch blocks, if (x != null) checks etc 

     // first download the image from the web 
     URL url = new URL(urlString); 
     HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
     connection.connect(); 

     BufferedInputStream bis = new BufferedInputStream(connection.getInputStream()); 
     Bitmap bitmap = BitmapFactory.decodeStream(bis); 
     bis.close() // (done in try-with-resource) 
     connection.disconnect(); 

     // then save the image on the device 
     File file = new File(App.context.getFilesDir(), "my/file/name.jpg"); 
     FileOutputStream fos = new FileOutputStream(file); 
     bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos); 
     fos.close() // (done in try-with-resource) 

     // make a Bundle, add some progress info and send it in a Message 
     handler.handleMessage(msg); 
    } 
} 

Моя проблема заключается в том, что это использует очень большой объем памяти. При просмотре монитора памяти в Android Studio он загружается до ~ 95 МБ при загрузке/сохранении каждого изображения (~ 1,7 МБ). Я использовал трекер распределения, чтобы внимательно посмотреть, и есть это одна линия, которая беспокоит меня:

(there are 6 images being downloaded)

Может кто-нибудь помочь мне понять, почему это происходит? Насколько я знаю, это «стандартный» способ загрузки изображений в Android.

+0

Почему вы используете AsyncTask вместо репликации с помощью обработчика? –

+1

Кроме того, почему вы берете поток, превращая его в растровое изображение, а затем превращая его в файл? Просто напишите поток прямо на диск. –

+0

Используйте DownloadManager для этого. Вот демо: http://blog.vogella.com/2011/06/14/android-downloadmanager-example/ –

ответ

0

Вы делаете промежуточные растровые изображения из своих файлов. Это занимает много памяти. Не используйте растровые изображения, но сохраняйте байты изображения непосредственно в файле. Возможно, вы, наверное, загрузите файл jpg.

Просто создайте цикл, в котором вы читаете фрагменты из входного потока и записываете их в выходной поток файла.

+0

Извините. Я только видел разговор об AsyncTasks, когда я разместил это. Теперь я вижу, что это уже упоминалось два раза. Я не должен был это делать. Сожалею. – greenapps

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