Recycle ImageView Bitmap
У меня есть что-то вроде этого:
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
WeakReference<Bitmap> bm = new WeakReference<Bitmap>(Bitmap.createBitmap(3000 + 3000, 2000, conf));
Canvas canvas = new Canvas(bm.get());
canvas.drawBitmap(firstBitmap, 0, 0, null);
canvas.drawBitmap(bm, firstBitmap.getWidth(), 0, null);
imageView.setImageBitmap(bm);
И я применяю это на более чем 10 imageView, которые создаются один за другим.
Всякий раз, когда я создаю новый ImageView, я хочу перерабатывать объект "bm" из первого, вызывать этот код там, заставляет кучу расти все больше и больше, а затем бросать OutOfMemoryError, поэтому я делаю:
bm.recycle()
сразу после того, как я установил Bitmap (bm) в объект imageView.
Это вызывает исключение, что холст ImageView хочет нарисовать переработанную растровую карту.
Каким образом можно переработать Bitmap, который уже был помещен как изображение в ImageView?
Thanksb
Ответы
Ответ 1
В вашем методе onDestroy вы можете попробовать что-то вроде этого:
ImageView imageView = (ImageView)findViewById(R.id.my_image);
Drawable drawable = imageView.getDrawable();
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
Bitmap bitmap = bitmapDrawable.getBitmap();
bitmap.recycle();
}
Приведение должно работать, поскольку setImageBitmap реализован как
public void setImageBitmap(Bitmap bm) {
setImageDrawable(new BitmapDrawable(mContext.getResources(), bm));
}
Ответ 2
Если вы установите один и тот же объект растрового изображения на всех своих ImageView
s, он не должен бросать OutOfMemoryError
. В принципе, это должно работать:
WeakReference<Bitmap> bm = new WeakReference<Bitmap>(Bitmap.createBitmap(3000 + 3000, 2000, Bitmap.Config.ARGB_8888));
Canvas canvas = new Canvas(bm.get());
canvas.drawBitmap(firstBitmap, 0, 0, null);
canvas.drawBitmap(bm, firstBitmap.getWidth(), 0, null);
imageView1.setImageBitmap(bm.get());
imageView2.setImageBitmap(bm.get());
imageView3.setImageBitmap(bm.get());
imageView4.setImageBitmap(bm.get());
imageView5.setImageBitmap(bm.get());
// ...
Если это не работает, это просто означает, что ваше растровое изображение слишком велико (6000x2000 пикселей составляет около 12 мегабайт, если я правильно рассчитал). Вы можете:
- сделать растровое изображение меньше
- сократить другие вещи, которые используют много памяти
Ответ 3
Ответ на Devconsole велик, но вы также можете хранить все объекты растровых изображений в списке как член вашего класса, а затем перерабатывать их в цикле, когда метод активности onDestroy() (или какой-либо другой метод жизненного цикла релиза компонента, в котором вы используете bitmap).
Ответ 4
Не создавайте изображения больше, чем вам нужно в любой момент времени. Ограничения кучи предназначены для того, чтобы вы не повесились и полностью захватили ограниченную память устройства.
Если вам нужно больше деталей, потому что вы планируете увеличивать масштаб, тогда повторно отрисуйте эту часть изображения с более высокой детализацией во время масштабирования, исключая части, которые вы не просматриваете.