Ошибка Android "Попытка использования переработанного растрового изображения"?
У меня проблема с растровыми изображениями в приложении для Android, над которым я работаю. Предполагается, что приложение загружает изображения с веб-сайта, сохраняет их на устройстве, загружает их в память в виде растровых изображений в arraylist и отображает их пользователю. Все это отлично работает, когда приложение запускается впервые. Тем не менее, я добавил параметр обновления для пользователя, где изображения удалены, и описанный выше процесс начинается на всем протяжении.
Моя проблема: с помощью опции обновления старые изображения все еще были в памяти, и я быстро получил OutOfMemoryErrors. Таким образом, если изображения обновляются, я пропустил это через arraylist и переработал старые изображения. Однако, когда приложение загружает новые изображения в arraylist, оно выходит из строя с ошибкой "Попробовать использовать переработанную растровую карту".
Насколько я понимаю, утилизация растрового изображения разрушает растровое изображение и освобождает память для других объектов. Если я хочу снова использовать битмап, его нужно повторно инициализировать. Я считаю, что делаю это, когда новые файлы загружаются в arraylist, но что-то по-прежнему не так. Любая помощь очень ценится, так как это очень расстраивает. Код проблемы приведен ниже. Спасибо!
public void fillUI(final int refresh) {
// Recycle the images to avoid memory leaks
if(refresh==1) {
for(int x=0; x<images.size(); x++)
images.get(x).recycle();
images.clear();
selImage=-1; // Reset the selected image variable
}
final ProgressDialog progressDialog = ProgressDialog.show(this, null, this.getString(R.string.loadingImages));
// Create the array with the image bitmaps in it
new Thread(new Runnable() {
public void run() {
Looper.prepare();
File[] fileList = new File("/data/data/[package name]/files/").listFiles();
if(fileList!=null) {
for(int x=0; x<fileList.length; x++) {
try {
images.add(BitmapFactory.decodeFile("/data/data/[package name]/files/" + fileList[x].getName()));
} catch (OutOfMemoryError ome) {
Log.i(LOG_FILE, "out of memory again :(");
}
}
Collections.reverse(images);
}
fillUiHandler.sendEmptyMessage(0);
}
}).start();
fillUiHandler = new Handler() {
public void handleMessage(Message msg) {
progressDialog.dismiss();
}
};
}
Ответы
Ответ 1
На самом деле вам не нужно вызывать метод утилизации. Кнопка Refresh должна просто очистить массив, сборщик мусора освободит память позже. Если вы получаете OutOfMemory, это означает, что некоторые другие объекты все еще ссылаются на ваши старые изображения, и сборщик мусора не может их удалить.
Я могу предположить, что некоторые ImageViews отображают ваши растровые изображения, и они содержат ссылки на эти растровые изображения. Вы не можете удалить старые растровые изображения, пока они все еще отображаются. Поэтому возможным решением является очистка ImageVIews. После этого вы можете очистить массив и заполнить его новыми изображениями.
Recycle освобождает память, но какой-то ImageView все еще отображает растровое изображение, и после этого он не может этого сделать, поэтому вы получаете "Попытка использовать переработанную растровую карту".
Все это всего лишь предположения, потому что я не вижу ваш полный код.
Ответ 2
Если память очень большая, вам лучше переработать растровое изображение.
GC не может контролироваться.