У меня есть активность, в которой пользователь нажимает кнопку, которая извлекает ответ 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 МБ). Я использовал трекер распределения, чтобы внимательно посмотреть, и есть это одна линия, которая беспокоит меня:
Может кто-нибудь помочь мне понять, почему это происходит? Насколько я знаю, это «стандартный» способ загрузки изображений в Android.
Почему вы используете AsyncTask вместо репликации с помощью обработчика? –
Кроме того, почему вы берете поток, превращая его в растровое изображение, а затем превращая его в файл? Просто напишите поток прямо на диск. –
Используйте DownloadManager для этого. Вот демо: http://blog.vogella.com/2011/06/14/android-downloadmanager-example/ –