Skip to content

Archives

  • enero 2022
  • diciembre 2021
  • noviembre 2021
  • octubre 2021
  • septiembre 2021
  • agosto 2021
  • julio 2021

Categories

  • No hay categorías
Twit Book ClubArticles
Articles

ANRs

On octubre 14, 2021 by admin

Cuando el hilo de la interfaz de usuario de una aplicación Android se bloquea durante demasiado tiempo, se produce un error «ApplicationNot Responding» (ANR). Si la aplicación está en primer plano, el sistema muestra un diálogo al usuario, como se muestra en la figura 1. El diálogo ANR da al usuario la oportunidad de forzar la salida de la aplicación.

Figura 1. Diálogo ANR mostrado al usuario

Los ANRs son un problema porque el hilo principal de la aplicación, que es responsable de actualizar la UI, no puede procesar los eventos de entrada del usuario o dibujar, causando frustración al usuario. Para obtener más información sobre el subproceso principal de la aplicación, consulte Procesos e hilos.

Se activará un ANR para su aplicación cuando se produzca una de las siguientes condiciones:

  • Mientras su actividad está en primer plano, su aplicación no ha respondido a un evento de entrada o BroadcastReceiver (como eventos de pulsación de teclas o de toque de pantalla) en 5 segundos.
  • Mientras no tienes una actividad en primer plano, tu BroadcastReceiver no ha terminado de ejecutarse en un tiempo considerable.

Si tu aplicación está experimentando ANRs, puedes usar la guía de este artículo para diagnosticar y solucionar el problema.

  • Detectar y diagnosticar problemas
  • Android vitals
  • Diagnóstico de ANRs
  • Modo estricto
  • Habilitar los diálogos ANR en segundo plano
  • Traceview
  • Trazar un archivo de trazas
  • Arreglar los problemas
  • Código lento en el hilo principal
  • IO en el hilo principal
  • Contención de bloqueos
  • Bloqueos
  • Receptores de difusión lenta

Detectar y diagnosticar problemas

Android proporciona varios medios para hacerle saber que su aplicación tiene un problema, y ayudarle a diagnosticarlo.Si ya ha publicado su aplicación, Androidvitals puede alertarle de que el problema está ocurriendo, yhay herramientas de diagnóstico para ayudarle a encontrar el problema.

Android vitals

Android vitals puede ayudar a mejorar el rendimiento de su aplicación alertándole, a través de laPlayConsole, cuando su aplicación está mostrando ANRs excesivos.Android vitals considera que las ANR son excesivas cuando una aplicación:

  • Muestra al menos una ANR en al menos el 0,47% de sus sesiones diarias.
  • Muestra 2 o más ANR en al menos el 0,24% de sus sesiones diarias.

Una sesión diaria se refiere a un día en el que se utilizó tu aplicación.

Para obtener información sobre cómo Google Play recopila los datos vitales de Android, consulte la documentación de Play Console.

Diagnóstico de ANRs

Hay algunos patrones comunes que se deben buscar al diagnosticar ANRs:

  1. La aplicación está realizando operaciones lentas que implican E/S en el hilo principal.
  2. La aplicación está realizando un cálculo largo en el hilo principal.
  3. El hilo principal está realizando una llamada binder síncrona a otro proceso, y ese otro proceso está tardando mucho en volver.
  4. El hilo principal está bloqueado esperando un bloque sincronizado para una operación larga que está ocurriendo en otro hilo.
  5. El hilo principal está en un punto muerto con otro hilo, ya sea en su proceso o a través de una llamada binder. El hilo principal no sólo está esperando a que termine una operación larga, sino que está en una situación de bloqueo. Para obtener más información, consulte Deadlock en Wikipedia.

Las siguientes técnicas pueden ayudarle a averiguar cuál de estas causas está provocando sus ANRs.

Modo estricto

Usar StrictMode le ayuda a encontrar operaciones de E/S accidentales en el hilo principal mientras está desarrollando su aplicación. Puedes utilizar StrictMode a nivel de aplicación o de actividad.

Habilitar los diálogos ANR en segundo plano

Android muestra los diálogos ANR para las aplicaciones que tardan demasiado en procesar el mensaje de difusión sólo si Mostrar todos los ANR está habilitado en las opciones de desarrollador del dispositivo. Por esta razón, los diálogos ANR en segundo plano no siempre se muestran al usuario, pero la aplicación aún podría estar experimentando problemas de rendimiento.

Traceview

Puedes utilizar Traceview para obtener un rastro de tu aplicación en ejecución mientras revisas los casos de uso e identificas los lugares donde el hilo principal está ocupado. Para obtener información sobre cómo utilizar Traceview, ver Perfiles con Traceview ydmtracedump.

Trazar un archivo de trazas

Android almacena información de trazas cuando experimenta un ANR. En las versiones más antiguas del sistema operativo, hay un único archivo /data/anr/traces.txt en el dispositivo.En las versiones más recientes del sistema operativo, hay varios archivos /data/anr/anr_*.Puedes acceder a las trazas de ANR desde un dispositivo o emulador utilizandoAndroid Debug Bridge (adb) como root:

adb rootadb shell ls /data/anradb pull /data/anr/<filename>

Puedes capturar un informe de errores desde un dispositivo físico utilizando la opción Take bugreport developer en el dispositivo, o el comando adb bugreport en tu máquina de desarrollo. Para obtener más información, consulte Capturar y leer informes de errores.

Arreglar los problemas

Después de haber identificado el problema, puede utilizar los consejos de esta sección para arreglar los problemas más comunes.

Código lento en el hilo principal

Identifique los lugares de su código en los que el hilo principal de la aplicación está ocupado durante más de 5 segundos. Busca los casos de uso sospechosos en tu aplicación e intenta reproducir el ANR.

Por ejemplo, la figura 2 muestra una línea de tiempo de Traceview en la que el hilo principal está ocupado durante más de 5 segundos.

Figura 2. Línea de tiempo de Traceview mostrando un hilo principal ocupado

La figura 2 nos muestra que la mayor parte del código infractor ocurre en el handler onClick(View), como se muestra en el siguiente ejemplo de código:

En este caso, deberías mover el trabajo que se ejecuta en el hilo principal a un workerthread. El Framework de Android incluye clases que pueden ayudar a mover la tarea a un hilo de trabajo. Ver Threading en Android para más información.

IO en el hilo principal

Ejecutar operaciones IO en el hilo principal es una causa común de operaciones lentas en el hilo principal, lo que puede causar ANRs. Se recomienda mover todas las operaciones IO a un hilo trabajador, como se muestra en la sección anterior.

Algunos ejemplos de operaciones IO son las operaciones de red y de almacenamiento. Para obtener más información, consulte Realización de operaciones de red y Almacenamiento de datos.

Contención de bloqueos

En algunos escenarios, el trabajo que causa el ANR no se ejecuta directamente en el hilo principal de la aplicación. Si un hilo trabajador mantiene un bloqueo en un recurso que el hilo principal requiere para completar su trabajo, entonces podría ocurrir un ANR.

Por ejemplo, la figura 4 muestra una línea de tiempo de Traceview donde la mayor parte del trabajo se realiza en un hilo trabajador.

Figura 4. Línea de tiempo de Traceview que muestra el trabajo que se ejecuta en un hilo worker

Pero si tus usuarios siguen experimentando ANRs, deberías mirar el estado del hilo principal en Android Device Monitor. Normalmente, el hilo principal está en el estado RUNNABLE si está listo para actualizar la interfaz de usuario y generalmente responde.

Pero si el hilo principal no puede reanudar la ejecución, entonces está en el estado BLOCKED y no puede responder a los eventos. El estado se muestra en el Android Device Monitor como Monitor o Wait, como se muestra en la figura 5.

Figura 5. Hilo principal en el estado Monitor

La siguiente traza muestra el hilo principal de una app que está bloqueado esperando una fuente:

Revisar la traza puede ayudarte a localizar el código que bloquea el hilo principal.El siguiente código es el responsable de mantener el bloqueo que bloquea el hilo principal en la traza anterior:

Otro ejemplo es el hilo principal de una app que está esperando un resultado de un hilo aworker, como se muestra en el siguiente código. Ten en cuenta que usar wait() ynotify() no es un patrón recomendado en Kotlin, que tiene sus propios mecanismos para manejar la concurrencia. Cuando se utiliza Kotlin, debe utilizar mecanismos específicos de Kotlin si es posible.

Hay algunas otras situaciones que pueden bloquear el hilo principal, incluyendohilos que utilizan Lock, Semaphore, así como un pool de recursos (como unool de conexiones de base de datos) u otros mecanismos de exclusión mutua (mutex).

Debería evaluar los bloqueos que su aplicación mantiene en los recursos en general, pero si quiere evitar ANRs, entonces debería mirar los bloqueos mantenidos para los recursos requeridos por el hilo principal.

Asegúrese de que los bloqueos se mantienen durante la menor cantidad de tiempo, o incluso mejor, evalúe si la aplicación necesita la retención en primer lugar. Si está utilizando el bloqueo para determinar cuándo actualizar la interfaz de usuario basado en el procesamiento de un hilo trabajador, utilice mecanismos como onProgressUpdate() y onPostExecute() para comunicarse entre el trabajador y los hilos principales.

Bloqueos

Un bloqueo se produce cuando un hilo entra en un estado de espera porque un recurso requerido es retenido por otro hilo, que también está esperando un recurso retenido por el primer hilo. Si el hilo principal de la aplicación se encuentra en esta situación, es probable que se produzcan ANRs.

Los bloqueos son un fenómeno bien estudiado en la ciencia de la computación, y hay algoritmos de prevención de bloqueos que se pueden utilizar para evitarlos.

Para más información, consulte Deadlock andDeadlock preventiongorithms enWikipedia.

Receptores de difusión lenta

Las aplicaciones pueden responder a los mensajes de difusión, como la activación o desactivación del modo avión o un cambio en el estado de conectividad, por medio de receptores de difusión. Se produce un ANR cuando una aplicación tarda demasiado en procesar el mensaje de difusión.

Se produce un ANR en los siguientes casos:

  • Un receptor de difusión no ha terminado de ejecutar su método onReceive() en un tiempo considerable.
  • Un receptor de difusión llama a goAsync()y no llama a finish() en el objeto PendingResult.

Tu aplicación sólo debería realizar operaciones cortas en el método onReceive() de un BroadcastReceiver. Sin embargo, si su aplicación requiere un procesamiento más complejo como resultado de un mensaje de difusión, debe diferir la tarea a un IntentService.

Puede utilizar herramientas como Traceview para identificar si su receptor de difusión ejecuta operaciones de larga duración en el hilo principal de la aplicación. Por ejemplo, la figura 6 muestra la línea de tiempo de un receptor de difusión que procesa un mensaje en el hilo principal durante aproximadamente 100 segundos.

Figura 6. Línea de tiempo de Traceview mostrando el trabajo del BroadcastReceiver en el hilo principal

Este comportamiento puede ser causado por la ejecución de operaciones de larga duración en el método onReceive() del BroadcastReceiver, como se muestra en el siguiente ejemplo:

En situaciones como estas, se recomienda mover la operación de larga duración a un IntentService porque utiliza un hilo trabajador para ejecutar su trabajo. El siguiente código muestra cómo utilizar un IntentService para procesar una operación de larga duración:

Como resultado de utilizar el IntentService, la operación de larga duración se ejecuta en un hilo de trabajo en lugar del hilo principal. La figura 7 muestra el trabajo diferido al hilo trabajador en la línea de tiempo de Traceview.

Figura 7. Línea de tiempo de Traceview mostrando el mensaje de difusión procesado en un hilo worker

Tu receptor de difusión puede utilizar goAsync() para indicar al sistema que necesita más tiempo para procesar el mensaje. Sin embargo, debe llamar a finish() en el objeto PendingResult. El siguiente ejemplo muestra cómo llamar a finish() para dejar que el sistema recicle el receptor de broadcast y evitar un ANR:

Sin embargo, mover el código de un receptor de broadcast lento a otro hilo y usar goAsync() no arreglará el ANR si el broadcast está en segundo plano. El tiempo de espera ANR todavía se aplica.

Para obtener más información sobre ANRs, verMantener la respuesta de su aplicación. Para obtener más información sobre los hilos, consulte Rendimiento de los hilos.

Deja una respuesta Cancelar la respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Entradas recientes

  • Himnos homéricos | Himno 5 : A Afrodita | Resumen
  • Salpicaderos
  • 9 Plantas Feng Shui para el Escritorio de la Oficina 2021 – Significado y Simbolismo
  • Especie casera para filetes de Montreal. Menos caro y usted controla el nivel de sal.
  • ¿Qué son las protuberancias que pican en la línea de la mandíbula y las mejillas?
  • Deutsch
  • Nederlands
  • Svenska
  • Dansk
  • Español
  • Français
  • Português
  • Italiano
  • Română
  • Polski
  • Čeština
  • Magyar
  • Suomi
  • 日本語

Archivos

  • enero 2022
  • diciembre 2021
  • noviembre 2021
  • octubre 2021
  • septiembre 2021
  • agosto 2021
  • julio 2021

Meta

  • Acceder
  • Feed de entradas
  • Feed de comentarios
  • WordPress.org

Copyright Twit Book Club 2022 | Theme by ThemeinProgress | Proudly powered by WordPress