Жесткий vs Один многоразовый битмап лучше с памятью?
Как я понимаю (не то, что я прав). Drawables, как правило, правильно удаляются из памяти, когда приложение завершается с ними. Однако растровые изображения необходимо вручную перерабатывать, а иногда даже иметь специальный класс, написанный для правильной обработки. Мой вопрос в том, что касается памяти и утечек, более выгодно просто придерживаться Drawables, например:
myView.setBackgroundDrawable(getResources().getDrawable(R.drawable.my_image));
myView1.setBackgroundDrawable(getResources().getDrawable(R.drawable.my_image1));
myView2.setBackgroundDrawable(getResources().getDrawable(R.drawable.my_image2));
а не что-то вроде этого с растровыми изображениями:
Bitmap tmpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image);
myView.setImageBitmap(tmpBitmap);
tmpBitmap.recycle();
tmpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image1);
myView1.setImageBitmap(tmpBitmap);
tmpBitmap.recycle();
tmpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image2);
myView2.setImageBitmap(tmpBitmap);
tmpBitmap.recycle();
Я также читал, конечно, что вы должны быть осторожны в методе recycle() на растровых изображениях, потому что их можно удалить, пока они еще используются? Кажется, что эти проблемы продолжают появляться в разных формах, но я не могу получить прямой ответ от кого-либо по этому вопросу. Один человек говорит, чтобы повторно использовать Bitmap и перерабатывать после каждого использования, а другие говорят, что используйте Drawables и метод unbindDrawables() (это то, что я использовал):
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
Любое применимое понимание было бы высоко оценено. Благодаря
Ответы
Ответ 1
Я возвращаю предложение Ромен, но я не уверен, что ваш вопрос касается вашей реальной проблемы. Я не знаю, как вы обрабатываете ссылки на свои представления. Может быть, у вас просто есть утечки памяти в вашем приложении? Многие утечки памяти в Android связаны с Context
. Когда a Drawable
привязан к View
, View
устанавливается как обратный вызов на Drawable
.
TextView myView = new TextView(this);
myView.setBackgroundDrawable(getDrawable(R.drawable.my_bitmap));
В приведенном выше фрагменте кода это означает, что Drawable
имеет ссылку на TextView
, которая сама имеет ссылку на Activity
(Context
), которая по очереди имеет ссылки на почти все, что зависит от ваш код.
Не смотря на более свой код, я думаю, что вы на правильном пути, установив обратные вызовы хранимых обращений к null
, когда Activity
будет уничтожен.
Ответ 2
Растровые изображения не нужно вручную перерабатывать. Это мусор, собранный так же, как Drawables и другие объекты. Точно так же вам не нужно развязывать чертежи, за исключением особых ситуаций. Кажется, что вы читаете много вводящей в заблуждение информации.
Утилизация растровых изображений и разворачивание может быть полезна в некоторых ситуациях (например, если ваше приложение управляет большими объемами растровых данных или если вы сохраняете их в виде статического образа.)
Два примера, которые вы показываете в начале вашего вопроса, эквивалентны. Если вы загружаете напрямую, растровые изображения будут загружены от вашего имени. Если вы загружаете растровые изображения вручную и устанавливаете их в ImageView, они будут вложены в чертежи от вашего имени.
Используйте первое решение, так как оно проще и не беспокоиться о развязывании и других методах управления памятью, пока вы им не понадобятся.