Как я могу контролировать поведение двойной буферизации Android?

Я пишу небольшую анимацию, в которой область должна начинаться с левой стороны экрана, расширяться, чтобы покрыть весь экран, и возвращаться назад. Я хочу, чтобы скорость менялась, но я обнаружил, что при высокой скорости появляется много «призрачных» изображений.

Сначала я пробовал с базовым View, а потом перешел на SurfaceView. Это было все еще призрачно. Я изучил рисунок на отдельном растровом изображении (буфере), представленном в этом вопросе.

Моя текущая версия кода рисования выглядит так:

Bitmap tempCanvasBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas screenCanvas = currentCanvasHolder.lockCanvas();
Canvas buffCanvas = new Canvas();
buffCanvas.setBitmap( tempCanvasBitmap );
blackRect.set( widthToPaint + 1, 0, viewWidth, viewHeight );
colorRect.set( 0, 0, widthToPaint, viewHeight );

buffCanvas.drawRect( blackRect, blackPaint );
buffCanvas.drawRect( colorRect, colorPaints[ currentColor ] );

screenCanvas.drawBitmap( tempCanvasBitmap, 0, 0, new Paint());

currentCanvasHolder.unlockCanvasAndPost( screenCanvas );

Но это все равно призрачно! Чтобы помочь в объяснении, я приложил пару видео анимации в ее текущем состоянии:


Пытаясь лучше понять проблему, я создал новый проект с линией, которая прыгает туда-сюда. В соответствии с рекомендациями документации Android относительно буферизации я каждый раз очищаю весь холст. Тем не менее, я все еще вижу, как линия «повторяется» несколько раз на протяжении всей анимации (после того, как она останавливается, она появляется сама по себе, чего я и ожидаю).

Проект можно найти по адресу https://github.com/thedanielgray/android-flickering-demo< /а> . Объединяет ли Android как-то все предыдущие буферы при рендеринге анимации? Я попытался нарисовать несколько линий, не очищая холст, и мне показалось, что было более 2 холстов / буферов, которые обменивались на разных этапах анимации. Какие параметры у меня есть для управления этим поведением буферизации?


person Daniel Gray    schedule 25.04.2017    source источник
comment
Не создавайте объекты Bitmap и Canvas снова и снова, если вы используете их повторно. Если для очистки экрана используется blackRect, то почему он не начинается с 0,0?   -  person resw67    schedule 26.04.2017
comment
Я использую blackRect для окрашивания неокрашенной части (widthToPaint — это разделительная координата X, где заканчивается цветная часть и начинается черная часть).   -  person Daniel Gray    schedule 26.04.2017
comment
Вот почему я это спросил. Сначала закрасьте все в черный цвет, а затем закрасьте часть в любой цвет.   -  person resw67    schedule 26.04.2017
comment
Попробовал это, и это все еще выглядит так же :( Думаю, я упускаю что-то еще...   -  person Daniel Gray    schedule 26.04.2017