Оптимизация пользовательского ImageView, который часто обновляется путем вызова onDraw.

Я создал собственный ImageView, и в его методе onDraw мне нужно нарисовать несколько растровых изображений на основе взаимодействия с пользователем, например касания. Все работает нормально, но медленно, когда я начинаю добавлять все больше и больше растровых изображений, приложение действительно замедляется.

Это то, что я делаю в своем onDraw пользовательского ImageView

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    Log.e(TAG, "onDraw called");

    for (int i=0; i < bitmapList.size(); i++){
        drawBitmap(canvas, bitmapList.get(i));
    }
}

Как вы можете видеть, я перерисовываю все растровые изображения в списке каждый раз, когда вызывается onDraw естественным образом, когда количество растровых изображений превышает, скажем, 4-5, операция становится очень дорогой и замедляет работу приложения.

Любое решение этой проблемы относительно того, как это можно оптимизировать?

  1. Может ли вызов drawBitmap в другом потоке сделать операцию менее затратной?

  2. Есть ли способ сохранить копию предыдущего холста, а затем просто восстановить его в onDraw, а не снова рисовать все растровые изображения?

  3. По сути, вопрос заключается в обновлении представления с большим количеством динамических изображений и его оптимизации.


person PravinCG    schedule 01.06.2011    source источник
comment
Привет, Правин, у тебя есть решение этой проблемы, я тоже столкнулся с той же проблемой. Пожалуйста, поделитесь своими выводами.   -  person Arpana    schedule 05.08.2014


Ответы (2)


Вы должны создать Bitmap, размер которого должен быть равен размеру изображения ImageView, и нарисовать все растровые изображения из bitmapList на этом растровом изображении только один раз. При каждом вызове onDraw() вы должны рисовать только это растровое изображение. При изменении bitmapList это дополнительное растровое изображение необходимо создать заново.

person Michael    schedule 01.06.2011
comment
Спасибо за ответ, я попробовал, и это действительно улучшает производительность, однако использование traceview показывает, что теперь метод, создающий bufferCanvas, занимает это время. Хотя это повышает производительность, так как теперь мне не нужно рисовать все растровые изображения каждый раз, когда вызывается onDraw, это все еще медленно, когда мне нужно обновить буферы. - person PravinCG; 01.06.2011
comment
Вы можете попытаться создать новый буфер каждый раз, когда вам нужно его обновить, и вы можете сделать это из отдельного потока. Думаю, это ускорит работу вашего приложения. - person Michael; 01.06.2011

Вы можете использовать изображение заднего буфера, чтобы рисовать все ваши изображения всякий раз, когда они меняются, а затем рисовать только изображение заднего буфера на экране в onDraw()

// create backbuffer and draw it as seldom as possible
final Bitmap bufferBitmap = Bitmap.createBitmap(320, 240, Bitmap.Config.ARGB_8888);
final Canvas bufferCanvas = new Canvas(bufferBitmap);
for (int i=0; i < bitmapList.size(); i++){
  drawBitmap(bufferCanvas, bitmapList.get(i));
  }

// draw the buffered image as often as needed
canvas.drawBitmap(bufferBitmap ...);
person Karl-Bjørnar Øie    schedule 01.06.2011
comment
... в основном тот же ответ, что и @Pixie дал вам .. :) - person Karl-Bjørnar Øie; 01.06.2011