2016-11-22 4 views
12

Используйте случай:Плохой производительности при непрерывном втягивания CustomView

Мне нужно рисовать сотни линий и несколько кусков текста на мой взгляд. Мне нужно дать эффект прокрутки, для которого я захватываю событие ACTION_MOVE и перерисовываю все строки с обновленными точками. Чтобы получить результат желания, я попытался с разными подходами, но никто не работает по назначению.

подход 1

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

подход 2

Я создал Bitmap и после нанесения всех строк на моей битовую карту в другом потоке, я использовал postInvalidate() нарисовать растровое изображение в onDraw() методе:

mBufferedBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); 
mBufferedBitmap.eraseColor(Color.TRANSPARENT);  
Canvas mBufferedCanvas = new Canvas(mBufferedBitmap);    
drawLines(mBufferedCanvas)  
postInvalidate(); 

Так как я стереть весь предыдущий рисунок на растровом изображении и нарисовать новые строки с обновленными точками, на экране появляется мерцание.

подход 3

Я попытался простирающийся свой собственный класс SurfaceView и выполнять все операции на объекте холст в другом потоке. Но так как SurfaceView использует процессор для операций рисования, производительность будет низкой в ​​мобильных телефонах с низкой конфигурацией.

Может ли кто-нибудь вести меня, как достичь этой задачи с лучшей производительностью?

+0

Попробуйте посмотреть в [ 'RenderScript'] (https://developer.android.com/guide/topics/renderscript/ compute.html). Я сам не использовал фреймворк, но это похоже на хороший прецедент. – Bryan

+0

RenderScript не понадобится для моего использования. – VijayRaj

+4

Не выделяйте новое растровое изображение в 'onDraw()', поэтому у вас есть fps. –

ответ

7

Для достижения хорошей производительности можно использовать подход .

Пример, который звучит рядом с вашим прецедентом (рисование линий, небольшой текст и наличие этих изменений при движении жестов) - MPAndroidChart. Это открытая библиотека источника, который обеспечивает высокую производительность (см the following comparison, если вы хотите статистику)

классов для изучения являются Renderer классами, поскольку они содержат код втягивание onDraw(Canvas c) диаграммы подтипов. Вы можете увидеть некоторые из трюков, используемых для достижения высокой производительности:

  1. Не выделяйте в цикле рендеринга. Вместо этого выделяйте вне цикла и повторно использовать/перерабатывать переменные. См. LineChartRendererline 199
  2. Использовать буферизацию. Например, в MPAndroidChart точки для четырех углов баров на гистограмме буферизуются, а буферный массив повторно используется. См. Класс BarBuffer.
  3. Используйте встроенные функции изображения Canvas (drawPath, drawLine и т. Д.)

Полный список советов по оптимизации рендеринга можно найти в Android Performance Slow Rendering Guide

2

подход 2 является одним из лучших вариантов. Если вы видите мерцание, это означает, что растровое изображение рисуется на экране после его удаления и перед тем, как вы нарисуете все линии. Если это так, используйте другое растровое изображение и делайте двойную буферизацию:

ScreenBitmap - это то, что нарисовано на экране OffScreenBitmap используется для рисования в фоновом режиме.

Нарисуйте все свои строки и текст на OffScreenBitmap, и как только закончите, скопируйте его в ScreenBitmap. в onDraw, нарисуйте ScreenBitmap.

Создание этих растровых изображений один раз (обычно в onSizeChanged), так что нет alloocation в OnDraw

Смежные вопросы