¿Hay alguna forma de averiguar dónde mi aplicación arrojó un ANR (la aplicación no responde)? Eché un vistazo al archivo traces.txt en / data y veo un rastro para mi aplicación. Esto es lo que veo en el rastro.
DALVIK THREADS:
"main" prio=5 tid=3 TIMED_WAIT
| group="main" sCount=1 dsCount=0 s=0 obj=0x400143a8
| sysTid=691 nice=0 sched=0/0 handle=-1091117924
at java.lang.Object.wait(Native Method)
- waiting on <0x1cd570> (a android.os.MessageQueue)
at java.lang.Object.wait(Object.java:195)
at android.os.MessageQueue.next(MessageQueue.java:144)
at android.os.Looper.loop(Looper.java:110)
at android.app.ActivityThread.main(ActivityThread.java:3742)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:497)
at dalvik.system.NativeStart.main(Native Method)
"Binder Thread #3" prio=5 tid=15 NATIVE
| group="main" sCount=1 dsCount=0 s=0 obj=0x434e7758
| sysTid=734 nice=0 sched=0/0 handle=1733632
at dalvik.system.NativeStart.run(Native Method)
"Binder Thread #2" prio=5 tid=13 NATIVE
| group="main" sCount=1 dsCount=0 s=0 obj=0x433af808
| sysTid=696 nice=0 sched=0/0 handle=1369840
at dalvik.system.NativeStart.run(Native Method)
"Binder Thread #1" prio=5 tid=11 NATIVE
| group="main" sCount=1 dsCount=0 s=0 obj=0x433aca10
| sysTid=695 nice=0 sched=0/0 handle=1367448
at dalvik.system.NativeStart.run(Native Method)
"JDWP" daemon prio=5 tid=9 VMWAIT
| group="system" sCount=1 dsCount=0 s=0 obj=0x433ac2a0
| sysTid=694 nice=0 sched=0/0 handle=1367136
at dalvik.system.NativeStart.run(Native Method)
"Signal Catcher" daemon prio=5 tid=7 RUNNABLE
| group="system" sCount=0 dsCount=0 s=0 obj=0x433ac1e8
| sysTid=693 nice=0 sched=0/0 handle=1366712
at dalvik.system.NativeStart.run(Native Method)
"HeapWorker" daemon prio=5 tid=5 VMWAIT
| group="system" sCount=1 dsCount=0 s=0 obj=0x4253ef88
| sysTid=692 nice=0 sched=0/0 handle=1366472
at dalvik.system.NativeStart.run(Native Method)
----- end 691 -----
¿Cómo puedo averiguar dónde está el problema? Los métodos en la traza son todos métodos SDK.
Gracias.
android
performance
android-anr-dialog
perdido en el transito
fuente
fuente
android.os.MessageQueue.nativePollOnce(Native Method)
. ¿Puedo ignorarlo con seguridad?Respuestas:
Un ANR ocurre cuando se realiza una operación larga en el hilo "principal". Este es el hilo del bucle de eventos, y si está ocupado, Android no puede procesar más eventos de GUI en la aplicación y, por lo tanto, arroja un cuadro de diálogo ANR.
Ahora, en el seguimiento que publicaste, el hilo principal parece estar bien, no hay problema. Está inactivo en MessageQueue, esperando que llegue otro mensaje. En su caso, el ANR probablemente fue una operación más larga, en lugar de algo que bloqueó el hilo permanentemente, por lo que el hilo del evento se recuperó después de que la operación finalizó, y su rastreo pasó. despues de la ANR.
Detectar dónde ocurren los ANR es fácil si es un bloqueo permanente (por ejemplo, un punto muerto que adquiere algunos bloqueos), pero es más difícil si se trata solo de un retraso temporal. Primero, revise su código y busque puntos vunerables y operaciones de larga duración. Los ejemplos pueden incluir el uso de enchufes, bloqueos, bloqueos de hilos y otras operaciones de bloqueo desde el hilo del evento. Debe asegurarse de que todo esto suceda en hilos separados. Si nada parece ser el problema, use DDMS y habilite la vista de hilo. Esto muestra todos los hilos en su aplicación similares a la traza que tiene. Reproduzca el ANR y actualice el hilo principal al mismo tiempo. Eso debería mostrarle exactamente lo que estaba sucediendo en el momento de la ANR
fuente
Puede habilitar StrictMode en el nivel de API 9 y superior.
fuente
Se pregunta qué tarea tiene un subproceso de interfaz de usuario. El archivo de seguimiento le da una pista para encontrar la tarea. necesitas investigar un estado de cada hilo
Estado del hilo
Centrarse en el estado SUSPENDIDO, MONITOREAR. El estado del monitor indica qué subproceso se investiga y el estado SUSPENDIDO del subproceso es probablemente la razón principal del punto muerto.
Pasos básicos de investigación
trace no siempre contiene "esperando para bloquear". En este caso es difícil encontrar la razón principal.
fuente
- waiting to lock an unknown object
adentro"HeapTaskDaemon" daemon prio=5 tid=8 Blocked
. ¿Qué significa que alguien puede ayudar?He estado aprendiendo Android durante los últimos meses, así que estoy lejos de ser un experto, pero me ha decepcionado mucho la documentación sobre los ANR.
La mayoría de los consejos parecen estar orientados a evitarlos o solucionarlos mirando a ciegas a través de su código, lo cual es genial, pero no pude encontrar nada al analizar el rastro.
Hay tres cosas que realmente debe buscar con los registros ANR.
1) Puntos muertos: cuando un hilo está en el estado de ESPERA, puede mirar a través de los detalles para encontrar a quién está "retenido =". La mayoría de las veces, se llevará a cabo solo, pero si está sujeto por otro hilo, es probable que sea una señal de peligro. Ve a mirar ese hilo y mira qué contiene. Es posible que encuentre un bucle, que es una clara señal de que algo salió mal. Esto es bastante raro, pero es el primer punto porque cuando sucede, es una pesadilla
2) Hilo principal en espera: si su hilo principal está en el estado ESPERAR, verifique si está en otro hilo. Esto no debería suceder, porque su subproceso de interfaz de usuario no debe estar retenido por un subproceso de fondo.
Ambos escenarios significan que debe volver a trabajar su código de manera significativa.
3) Operaciones pesadas en el hilo principal: esta es la causa más común de ANR, pero a veces es una de las más difíciles de encontrar y solucionar. Mira los detalles del hilo principal. Desplácese hacia abajo por el seguimiento de la pila y hasta que vea las clases que reconoce (desde su aplicación). Mire los métodos en la traza y descubra si está haciendo llamadas de red, llamadas db, etc. en estos lugares.
Finalmente, y me disculpo por enchufar descaradamente mi propio código, puede usar el analizador de registro de Python que escribí en https://github.com/HarshEvilGeek/Android-Log-Analyzer Esto revisará sus archivos de registro, abrirá archivos ANR, encontrará puntos muertos, encontrar subprocesos principales en espera, encontrar excepciones no detectadas en los registros de su agente e imprimirlo todo en la pantalla de una manera relativamente fácil de leer. Lea el archivo Léame (que estoy a punto de agregar) para aprender cómo usarlo. ¡Me ha ayudado mucho en la última semana!
fuente
Siempre que esté analizando problemas de tiempo, la depuración a menudo no ayuda, ya que congelar la aplicación en un punto de interrupción hará que el problema desaparezca.
Su mejor opción es insertar muchas llamadas de registro (Log.XXX ()) en los diferentes hilos y devoluciones de llamadas de la aplicación y ver dónde está el retraso. Si necesita un seguimiento de pila, cree una nueva Excepción (solo cree una instancia) y regístrela.
fuente
¿Qué desencadena ANR?
Generalmente, el sistema muestra un ANR si una aplicación no puede responder a la entrada del usuario.
En cualquier situación en la que su aplicación realice una operación potencialmente larga, no debe realizar el trabajo en el subproceso de interfaz de usuario, sino crear un subproceso de trabajo y hacer la mayor parte del trabajo allí. Esto mantiene el subproceso de la interfaz de usuario (que controla el bucle de eventos de la interfaz de usuario) y evita que el sistema concluya que su código se ha congelado.
Cómo evitar los ANR
Las aplicaciones de Android normalmente se ejecutan completamente en un solo subproceso de forma predeterminada el "subproceso de interfaz de usuario" o "subproceso principal"). Esto significa que cualquier cosa que su aplicación esté haciendo en el subproceso de interfaz de usuario que tarde mucho tiempo en completarse puede activar el cuadro de diálogo ANR porque su aplicación no se está dando la oportunidad de manejar el evento de entrada o las transmisiones intencionales.
Por lo tanto, cualquier método que se ejecute en el subproceso de la interfaz de usuario debe hacer el menor trabajo posible en ese subproceso. En particular, las actividades deben hacer lo menos posible para establecerse en métodos clave del ciclo de vida como onCreate () y onResume (). Las operaciones de ejecución potencialmente prolongada, como las operaciones de red o de base de datos, o los cálculos computacionalmente costosos, como el cambio de tamaño de los mapas de bits, se deben realizar en un subproceso de trabajo (o en el caso de operaciones de bases de datos, a través de una solicitud asincrónica).
Código: hilo de trabajo con la clase AsyncTask
Código: Ejecutar hilo de trabajo
Para ejecutar este hilo de trabajo, simplemente cree una instancia y llame a execute ():
Fuente
http://developer.android.com/training/articles/perf-anr.html
fuente
mi problema con ANR, después de mucho trabajo descubrí que un hilo estaba llamando a un recurso que no existía en el diseño, en lugar de devolver una excepción, obtuve ANR ...
fuente
Debe buscar "esperando para bloquear" en el archivo /data/anr/traces.txt
para más detalles: ingeniero de alto rendimiento con herramientas de Android y Play (Google I / O '17)
fuente
Básico en la respuesta de @Horyun Lee, escribí un pequeño script de Python para ayudar a investigar ANR
traces.txt
.Los ANR se generarán como gráficos
graphviz
si los ha instaladograpvhviz
en su sistema.Se generará un png como el siguiente si se detectan ANR en el archivo
traces.txt
. Es mas intuitivo.El
traces.txt
archivo de muestra utilizado anteriormente fue obtener de aquí .fuente
Considere usar la biblioteca ANR-Watchdog para rastrear y capturar con precisión los rastros de la pila ANR con un alto nivel de detalle. Luego puede enviarlos a su biblioteca de informes de fallas. Recomiendo usar
setReportMainThreadOnly()
en este escenario. Puede hacer que la aplicación arroje una excepción no fatal del punto de congelación o hacer que la aplicación se cierre forzosamente cuando ocurre el ANR.Tenga en cuenta que los informes ANR estándar enviados a su consola de Google Play Developer a menudo no son lo suficientemente precisos como para identificar el problema exacto. Es por eso que se necesita una biblioteca de terceros.
fuente