Я работаю над живыми обоями с прокруткой. У меня есть два объекта растровых изображений, которые я чередую, чтобы сохранить ранее нарисованные пиксели для следующего кадра. Я рисую новую строку в верхней части холста, а затем вызываю drawBitmap, чтобы скопировать остальные пиксели на холст.
Я использую объект Runnable для тяжелого подъема. Он выполняет все операции копирования и вычисления, а затем блокирует холст, вводит синхронный блок на держателе и делает один вызов Canvas.drawBitmap(растровое изображение, прямоугольник, прямоугольник, краска). Иногда на экране появляется белая вспышка, которая, похоже, коррелирует с высокой активностью процессора. При использовании traceview я обнаружил, что операция drawBitmap, в частности Canvas.native_drawBitmap(), занимает гораздо больше времени, чем обычно. Обычно он заканчивается в 2-4 мсек, но когда я вижу белую вспышку, она может занять от 10 до 100 мсек.
private void draw() {
SurfaceHolder holder = getSurfaceHolder();
Canvas canvas = null;
prepareFrame();
try {
canvas = holder.lockCanvas();
synchronized (holder) {
if (canvas != null) {
drawFrame(canvas);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (canvas != null)
holder.unlockCanvasAndPost(canvas);
}
afterDrawFrame();
handler.removeCallbacks(drawRunner);
if (visible) {
handler.post(drawRunner);
}
}
Функция draw()
вызывается в run()
Runnable.
private void prepareFrame() {
num++;
if (num%2 == 0) {
mainBmp = mainBmp1;
mainCan.setBitmap(mainBmp1);
mainCan.drawBitmap(mainBmp2, source, destination, null);
} else {
mainBmp = mainBmp2;
mainCan.setBitmap(mainBmp2);
mainCan.drawBitmap(mainBmp1, source, destination, null);
}
}
Функция prepareFrame()
заключается в том, как я сохраняю предыдущие пиксели, которые я нарисовал. Rect, называемый источником, - это одна строка, которая меньше полного размера экрана внизу, где в качестве места назначения находится одна строка в верхней части. Вызов drawBitmap()
в prepareFrame()
не превышает 2-4 мсек.
private void drawFrame(Canvas can) {
can.drawBitmap(mainBmp, source, destination,null);
}
Эта одиночная операция выполняется на холсте, удерживая блокировку.
private void afterDrawFrame() {
ca.calcNextRow();
mainBmp.setPixels(ca.getRow(), 0, canWidth, 0, 0, canWidth, 1);
}
Затем следующая новая строка пикселей нарисована на одном из моих растровых изображений в памяти.
Я попытался использовать различные подписи drawBitmap()
, но только нашел их более медленными в среднем и все еще приводят к аномальным белым вспышкам.
Моя общая скорость отличная. Без прерывистых вспышек он работает очень хорошо. У кого-нибудь есть предложения по устранению вспышек?