Simple TextView.setText causa 40% de uso de CPU

Ejecutar mi aplicación provoca ~ 40% de uso de la CPU en mi teléfono:

final String position = String.format("%02d:%02d:%02d", time.getHours(), time.getMinutes(), time.getSeconds()); getActivity().runOnUiThread(new Runnable() { @Override public void run() { c.mTxtPosition.setText(position); ... 

Al comentar el método setText , el uso de la CPU disminuye al nivel esperado de ~ 4%. El método se invoca cada segundo y actualiza ImageViews, CustomViews … sin causar el mismo exceso de carga. Además de la CPU Uso dalvik constantemente informes recolección de basura de alrededor de 10-1000 objetos con sólo llamar a setText () .

Creación de un tracefile como este:

 Debug.startMethodTracing("setText"); c.mTxtPosition.setText(position); Debug.stopMethodTracing(); 

Traceview enumera los siguientes métodos como Top 5 por su respectiva CPU exclusiva%:

  • ViewParent.invalidateChildInParent (16%)
  • View.requestLayout (11%)
  • ViewGroup.invalidateChild (9%)
  • TextView.setText (7%)
  • Toplevel (6%)

¿Alguien tiene una explicación para esto?

Me di cuenta de esto yo hace un tiempo, creo que el problema es que cada vez que llame a setText, el tamaño de la caja de texto puede cambiar, por lo tanto, toda la pantalla necesita pasar por relayout (caro).

Todavía no he probado esto, pero si su caja de texto es simple y se puede hacer que sea un tamaño relativamente fijo, tal vez intente subclase TextView y cree una vista que no se redimensione en setText, sino que dibuje lo que sea En el área existente? Eso ahorraría mucho tiempo.

Tal vez ya hay una bandera para setText que puede hacer que lo haga, pero no soy consciente de ello, aunque no he buscado de cerca.

En mi caso, actualizo un TextView desde el evento touch, lo que causa una gran cantidad de actualización. La solución fue cambiar el layout_width y layout_height de TextView a tamaño fijo.

Algunas mejoras posibles:

  1. Intente usar un controlador que actualiza la vista de texto cada 0,5 segundos en lugar de un subproceso que lo hace.
  2. Hacen que el runnable sea un objeto final constante en lugar de crear un nuevo cada segundo.
  3. Considere la posibilidad de comprobar que la hora ha cambiado (newTimeInMs-LastPublishedTimeInMs> = 1000) antes de decirle al textview que se actualice.
  4. En lugar de String.format, intente usar StringBuilder. Sin embargo, no podrá disfrutar de la solución de configuración regional que proporciona String.format (por ejemplo, para los dígitos árabes).

En mi caso fue esta propiedad de TextView:

 android:ellipsize="marquee" 

Eliminarla aceleró la configuración del texto.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.