Подтвердить что ты не робот

Жесткий 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();
    }
}

Любое применимое понимание было бы высоко оценено. Благодаря

4b9b3361

Ответ 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, они будут вложены в чертежи от вашего имени.

Используйте первое решение, так как оно проще и не беспокоиться о развязывании и других методах управления памятью, пока вы им не понадобятся.