Significado de los mensajes del coreógrafo en Logcat

Instalé las últimas versiones de SDK (API 16) y obtuve el último ADT. Ahora estoy viendo estos mensajes en el logcat, que estoy bastante seguro, no he visto antes. ¿Alguien tiene una idea sobre esto?

06-29 23: 11: 17.796: I / coreógrafo (691): se saltaron 647 cuadros! La aplicación puede estar haciendo demasiado trabajo en su hilo principal.

Hice una búsqueda y encontré este enlace: http://developer.android.com/reference/android/view/Choreographer.html . Esta es una nueva clase presentada en API 16.

Necesito saber cómo puedo determinar el “trabajo excesivo” que puede hacer mi aplicación, ya que todo el procesamiento se realiza en AsyncTask .

Coreógrafo permite que las aplicaciones se conecten a la vsync, y cronometrar las cosas para mejorar el rendimiento.

Las animaciones de vista de Android utilizan internamente Choreographer con el mismo objective: sincronizar correctamente las animaciones y posiblemente mejorar el rendimiento.

Como a Coreógrafo se le informa sobre cada evento vsync, puedo decir si uno de los Runnables transferidos por Choreographer.post * apis no termina en el tiempo de un fotogtwig, lo que hace que se omitan los fotogtwigs.

En mi comprensión, Coreógrafo solo puede detectar el salto de cuadros. No tiene forma de decir por qué sucede esto.

El mensaje “La aplicación puede estar haciendo demasiado trabajo en su hilo principal”. podría ser engañoso.

Llego tarde a la fiesta, pero espero que esto sea una adición útil a las otras respuestas aquí …

Respondiendo a la pregunta / tl: dr;

Necesito saber cómo puedo determinar el “trabajo excesivo” que puede hacer mi aplicación, ya que todo el procesamiento se realiza en AsyncTasks.

Los siguientes son todos candidatos:

  • IO o el procesamiento costoso en el hilo principal (carga de elementos extraíbles, inflado de diseños y configuración de Uri en ImageView todos IO en el hilo principal)
  • Representación grande / compleja / profunda View jerarquías
  • Invalidar porciones grandes de una jerarquía de View
  • onDraw caros onDraw en View personalizadas
  • Cálculos caros en animaciones
  • Ejecutar subprocesos “de trabajo” con demasiada prioridad como para ser considerados “de fondo” ( AsyncTask son “de fondo” de forma predeterminada, java.lang.Thread no )
  • Generando mucha basura, haciendo que el recolector de basura “pare el mundo”, incluido el hilo principal, mientras limpia

Para determinar realmente la causa específica, necesitarás crear un perfil de tu aplicación.

Mas detalle

He intentado comprender a Coreógrafo al experimentar y mirar el código .

La documentación de Choreographer se abre con “Coordina el tiempo de las animaciones, la entrada y el dibujo”. que en realidad es una buena descripción, pero el rest continúa enfatizando demasiado las animaciones.

El coreógrafo es en realidad responsable de ejecutar 3 tipos de devoluciones de llamada, que se ejecutan en este orden:

  1. Devolución de llamadas de manejo de entrada (manejo de entrada de usuario como eventos táctiles)
  2. devoluciones de llamada de animación para interpolación entre fotogtwigs, que proporciona un inicio de fotogtwig estable para cualquiera / todas las animaciones que se están ejecutando. Ejecutar estas devoluciones en segundo lugar significa que ya se han realizado los cálculos relacionados con la animación (por ejemplo, cambiar las posiciones de las View) cuando se invoca el tercer tipo de callback …
  3. ver las devoluciones de llamada cruzadas para dibujar la jerarquía de vista.

El objective es hacer coincidir la velocidad a la que se vuelven a dibujar las vistas invalidadas (y las animaciones interpoladas) con la pantalla vsync, normalmente 60 fps.

La advertencia sobre marcos omitidos parece una ocurrencia tardía: el mensaje se registra si una sola pasada a través de los 3 pasos requiere más de 30 veces la duración de cuadro esperada, por lo que el número más pequeño que puede esperar en los mensajes de registro es “omitido 30 cuadros” ; Si cada pase tarda un 50% más de lo que debería, salteará 30 cuadros ( ¡travieso! ) Pero no se lo advertirá.

De los 3 pasos involucrados está claro que no son solo las animaciones las que pueden desencadenar la advertencia: invalidar una porción significativa de una gran jerarquía de View o una View con un complicado método onDraw podría ser suficiente.

Por ejemplo, esto disparará la advertencia repetidamente:

 public class AnnoyTheChoreographerActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simple_linear_layout); ViewGroup root = (ViewGroup) findViewById(R.id.root); root.addView(new TextView(this){ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); long sleep = (long)(Math.random() * 1000L); setText("" + sleep); try { Thread.sleep(sleep); } catch (Exception exc) {} } }); } } 

… que produce el registro de esta manera:

 11-06 09:35:15.865 13721-13721/example I/Choreographer﹕ Skipped 42 frames! The application may be doing too much work on its main thread. 11-06 09:35:17.395 13721-13721/example I/Choreographer﹕ Skipped 59 frames! The application may be doing too much work on its main thread. 11-06 09:35:18.030 13721-13721/example I/Choreographer﹕ Skipped 37 frames! The application may be doing too much work on its main thread. 

Puede ver en la stack durante onDraw que el coreógrafo está involucrado independientemente de si está animando:

en example.AnnoyTheChoreographerActivity $ 1.onDraw (AnnoyTheChoreographerActivity.java:25) en android.view.View.draw (View.java:13759)

… bastante repetición …

en android.view.ViewGroup.drawChild (ViewGroup.java:3169) en android.view.ViewGroup.dispatchDraw (ViewGroup.java:3039) en android.view.View.draw (View.java:13762) en android.widget. FrameLayout.draw (FrameLayout.java:467) en com.android.internal.policy.impl.PhoneWindow $ DecorView.draw (PhoneWindow.java:2396) en android.view.View.getDisplayList (View.java:12710) en android .view.View.getDisplayList (View.java:12754) en android.view.HardwareRenderer $ GlRenderer.draw (HardwareRenderer.java:1144) en android.view.ViewRootImpl.draw (ViewRootImpl.java:2273) en android.view. ViewRootImpl.performDraw (ViewRootImpl.java:2145) en android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:1956) en android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1112) en android.view.ViewRootImpl $ TraversalRunnable.run (ViewRootImpl.java:4472) en android.view.Coreographer $ CallbackRecord.run (Choreographer.java:725) en android.view.Choreographer.doCallbacks (Choreographer.java:555) en android.view.Choreographer.doFrame (Cho reographer.java:525) en android.view.Coreographer $ FrameDisplayEventReceiver.run (Choreographer.java:711) en android.os.Handler.handleCallback (Handler.java:615) en android.os.Handler.dispatchMessage (Handler.java : 92) en android.os.Looper.loop (Looper.java:137) en android.app.ActivityThread.main (ActivityThread.java:4898)

Finalmente, si hay contención de otros subprocesos que reducen la cantidad de trabajo que se puede realizar el hilo principal, la posibilidad de omitir fotogtwigs aumenta dramáticamente a pesar de que en realidad no está haciendo el trabajo en el hilo principal.

En esta situación, podría considerarse engañoso sugerir que la aplicación está haciendo demasiado en el hilo principal, pero Android realmente quiere que los subprocesos de trabajo se ejecuten con baja prioridad para evitar que mueran de hambre el hilo principal. Si sus subprocesos de trabajo son de baja prioridad, la única forma de activar la advertencia de Coreógrafo es hacer demasiado en el subproceso principal.

Esto es un mensaje de información que podría aparecer en tu LogCat en muchas situaciones.

En mi caso, sucedió cuando estaba inflando varias vistas desde archivos de diseño XML programáticamente. El mensaje es inofensivo por sí mismo, pero podría ser el signo de un problema posterior que usaría toda la memoria RAM que su aplicación tiene permitido usar y provocaría el mega-malvado Force Close. He crecido para ser el tipo de Desarrollador al que le gusta ver su Log WARN / INFO / ERROR Free. 😉

Entonces, esta es mi propia experiencia:

Recibí el mensaje:

 10-09 01:25:08.373: I/Choreographer(11134): Skipped XXX frames! The application may be doing too much work on its main thread. 

… cuando estaba creando mi propia “lista de multisecciones súper complejas” inflando una vista desde XML y poblando sus campos (imágenes, texto, etc.) con los datos provenientes de la respuesta de un REST / Servicio web JSON (sin capacidades de paginación) estas vistas actuarían como filas, encabezados de subsecciones y encabezados de sección al agregarlos todos en el orden correcto a LinearLayout (con orientación vertical dentro de ScrollView). Todo eso para simular una ListView con elementos seleccionables … pero bueno, eso es para otra pregunta.

Como Desarrollador responsable, desea hacer que la Aplicación sea realmente eficiente con los recursos del sistema, por lo que la mejor práctica para las listas (cuando sus listas no son tan complejas) es usar una ListActivity o ListFragment con un Loader y llenar el ListView con un Adaptador, esto es supuestamente más eficiente, de hecho lo es y deberías hacerlo todo el tiempo, nuevamente … si tu lista no es tan compleja.

Solución: Implementé paginación en mi servicio web REST / JSON para evitar “grandes tamaños de respuesta” y envolví el código que agregaba las vistas “filas”, “encabezados de sección” y “encabezados de subsección” en un AsyncTask para mantener el Main Hilo de rosca

Entonces … espero que mi experiencia ayude a alguien más que se está abriendo la cabeza con este mensaje de información.

¡Feliz hacking!

Esto generalmente ocurre cuando se depura usando el emulador, que se sabe que es lento de todos modos.

En mi caso tengo estos mensajes cuando muestro la barra de acción de sherlock inderterminate progressbar. Como no es mi biblioteca, decidí ocultar las salidas del coreógrafo.

Puede ocultar las salidas de Coreógrafo en la vista de Logcat, usando esta expresión de filtro:

etiqueta: ^ ((?! coreógrafo). *) $

Utilicé una expresión regular explicada en otra parte: expresión regular para que coincida con una línea que no contiene una palabra?