Malo rendimiento al dibujar continuamente en CustomView

Caso de uso:

Necesito dibujar cientos de líneas y pocos textos en mi vista. Necesito dar un efecto de desplazamiento, por lo que captura el evento ACTION_MOVE y ACTION_MOVE dibujar todas las líneas con los puntos actualizados. Para obtener el resultado de deseo que he intentado con diferentes enfoques, pero ninguno funciona como estaba previsto.

Enfoque 1

Hice una clase personalizada que amplía la View . Todo el dibujo y cálculo se realiza directamente en mi método onDraw() . Dado que hay tanta operación realizada en el método onDraw() , el rendimiento de la aplicación es muy pobre. Incluso he comprobado el rendimiento mediante la renderización de perfil GPU y puedo ver las líneas son muy altas.

Enfoque 2

He creado un mapa de bits y después de dibujar todas las líneas en mi mapa de bits en otro hilo, he utilizado postInvalidate() para dibujar el mapa de bits en el método onDraw()

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

Puesto que borro todo el dibujo anterior en el mapa de bits y dibujo nuevas líneas con puntos actualizados, hay un parpadeo en la pantalla.

Enfoque 3

He intentado ampliar mi clase personalizada a SurfaceView y realizar todas las operaciones en el objeto de lienzo en otro hilo. Pero como SurfaceView utiliza la CPU para las operaciones de dibujo, el rendimiento será pobre en los móviles de configuración baja.

¿Puede alguien guiarme cómo lograr esta tarea con un mejor rendimiento?

Es posible utilizar su enfoque 1 para lograr un buen rendimiento.

Un ejemplo que suena cerca de su caso de uso (líneas de dibujo, un poco de texto y tener estas actualizaciones sobre el movimiento de gestos) es MPAndroidChart . Se trata de una biblioteca de código abierto que logra un alto rendimiento (consulte la siguiente comparación si desea estadísticas)

Las clases a examinar son las clases Renderer , ya que contienen código dibujar en el onDraw(Canvas c) de los subtipos de gráfico. Usted puede ver algunos de los trucos utilizados para lograr un alto rendimiento allí:

  1. No asignar en un bucle de render. En su lugar, asignar fuera del bucle y reutilizar / reciclar variables. Consulte LineChartRenderer línea 199
  2. Utilizar el almacenamiento en búfer. Por ejemplo, en MPAndroidChart, los puntos de las cuatro esquinas de las barras del gráfico de barras se almacenan en búfer y se vuelve a utilizar el arreglo de búfer. Vea la clase BarBuffer .
  3. Utilice las funciones de dibujo de Canvas nativas ( drawPath , drawLine , etc.)

El enfoque 2 es el mejor. Si ve parpadeo, significa que el mapa de bits se dibuja a la pantalla después de borrarlo y antes de dibujar todas las líneas. Si este es el caso, utilice otro mapa de bits y realice un doble almacenamiento en búfer:

ScreenBitmap es lo que se dibuja a la pantalla OffScreenBitmap se utiliza para dibujar en segundo plano.

Dibuja todas tus líneas y texto a OffScreenBitmap, y una vez terminado, copia a ScreenBitmap. En onDraw, dibuje el ScreenBitmap.

Cree estos mapas de bits una vez (normalmente en onSizeChanged), para que no haya alloocation en onDraw

  • Android Cámara de visión de superficie cámara recreada cuando presiono botón de nuevo en la tableta de Archos en jellybean
  • Android IllegalArgumentException lockCanvas ()
  • El lienzo SurfaceView de Android produce colores incorrectos
  • Evitar el "parpadeo" al llamar a Drawable.draw ()
  • ¿Cómo utilizar el feed de cámara en vivo como un fondo de actividad?
  • Android OpenGL que extiende las excepciones de puntero nulo de GLSurfaceView
  • Android: vista de la cámara: la aplicación se bloquea cuando no utilizo un método obsoleto
  • Cámara de conmutación de adelante hacia atrás en pjsip android
  • escala de previsualización de la cámara para adaptarse a la mitad de la pantalla
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.