Работаю над живыми обоями с прокручивающимся фоном.У меня есть два растровых объекта, между которыми я чередую, чтобы сохранить ранее нарисованные пиксели для следующего кадра. Я рисую новую линию в верхней части холста, затем вызываю функцию drawBitmap, чтобы скопировать остальные пиксели на холст.
Я использую объект Runnable для выполнения тяжелой работы. Он выполняет все необходимые операции копирования и вычислений, а затем блокирует холст, вводит синхронный блок на держателе и выполняет единственный вызов Canvas.drawBitmap(bitmap,rect,rect,paint). Время от времени на экране появляется белая вспышка, что, по-видимому, связано с высокой активностью процессора. При использовании 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()
, но обнаружил, что в среднем они работают медленнее и все равно приводят к аномальным белым вспышкам.
Моя общая скорость отличная.Без прерывистых вспышек работает очень хорошо. У кого-нибудь есть предложения по устранению вспышек?