Organiza tus páginas con colecciones
Guarda y categoriza el contenido según tus preferencias.
Figura 1: Diálogo de ANR que se le muestra al usuario
En este documento, se describe la manera en que el sistema Android determina si una app no responde y se muestra cómo mantener la capacidad de respuesta de tu app.
Sin importar qué tan bien escrito esté el código, es posible que tu app se vea lenta, se bloquee o tarde demasiado tiempo en procesar los datos de entrada. Si tu app está en primer plano y no responde, el usuario verá un diálogo de Aplicación no responde (ANR), como se muestra en la figura 1. El diálogo de ANR permite que el usuario fuerce el cierre de la app. Si la app no está en primer plano, se detiene en silencio. Es fundamental diseñar la capacidad de respuesta de tu app para minimizar los diálogos de ANR.
Activadores de ANR
Por lo general, el sistema muestra un error de ANR si una app no puede responder a la entrada del usuario en el subproceso principal (también conocido como subproceso de IU), lo que impide que el sistema procese estos eventos de entrada.
Por ejemplo, puede producirse un error de ANR si una app realiza una operación de bloqueo de E/S, como el acceso a la red, en el subproceso de IU. Otro ejemplo es cuando una app tarda demasiado creando una estructura en memoria elaborada o calculando el siguiente movimiento en un juego en el subproceso de IU.
En Android, los servicios del sistema ActivityManager y WindowManager supervisan la capacidad de respuesta de las apps. Android muestra el diálogo de ANR de una app cuando detecta una de las siguientes condiciones:
No se produce una respuesta a un evento de entrada (como presionar la pantalla o usar las teclas) después de 5 segundos.
Las siguientes son sugerencias generales para evitar los errores de ANR. Si quieres obtener más información para diagnosticar y depurar diferentes tipos de errores de ANR, consulta las otras páginas de esta sección.
Mantén el subproceso principal desbloqueado en todo momento y usa los subprocesos de forma estratégica.
No realices operaciones de bloqueo ni de larga duración en el subproceso principal de la app.
En su lugar, crea un subproceso de trabajo y haz la mayor parte del trabajo allí.
Intenta minimizar cualquier contención de bloqueo entre el subproceso principal y otros subprocesos.
Minimiza cualquier trabajo no relacionado con la IU en el subproceso principal, como cuando se manejan transmisiones o se ejecutan servicios. Cualquier método que se ejecute en el subproceso de IU debe realizar el menor trabajo posible en ese subproceso. En particular, las actividades deben hacer lo mínimo posible para configurarse en métodos clave de ciclo de vida, como onCreate() y onResume(). Consulta Descripción general del trabajo en segundo plano para obtener más información sobre las soluciones disponibles para programar el trabajo en un subproceso en segundo plano y comunicarse con la IU.
Ten cuidado cuando compartas grupos de subprocesos entre componentes. No uses los mismos subprocesos para operaciones que podrían ser de bloqueo prolongado y tareas urgentes, como la recepción de transmisiones.
Procura que el inicio de la app sea rápido. Minimiza las operaciones lentas o de bloqueo en el código de inicio de la app, como los métodos que se ejecutan durante la inicialización de Dagger.
Si usas goAsync(), asegúrate de que se llame a PendingResult.finish rápidamente antes de que se agote el tiempo de espera del error de ANR.
Errores de ANR en BroadcastReceiver
El tiempo de ejecución de BroadcastReceiver está limitado porque los receptores de emisión están destinados a realizar cantidades pequeñas y discretas de trabajo en segundo plano, como guardar una opción de configuración o registrar una Notification. Al igual que con otros métodos llamados en el subproceso de IU, las apps deben evitar las operaciones o los cálculos de larga duración en un receptor de emisión. En lugar de realizar tareas de larga duración a través del subproceso de IU, ejecútalas en segundo plano para una ejecución posterior. Consulta Descripción general del trabajo en segundo plano para obtener más información sobre posibles soluciones.
Otro problema común se presenta cuando los objetos BroadcastReceiver se ejecutan con demasiada frecuencia. La ejecución frecuente en segundo plano puede reducir la cantidad de memoria disponible para otras apps. Para obtener más información sobre cómo habilitar o inhabilitar objetos BroadcastReceiver de manera eficiente, consulta la Descripción general de las transmisiones.
Cómo reforzar la capacidad de respuesta
Por lo general, es de 100 a 200 ms el umbral más allá del cual los usuarios perciben la lentitud en una app. A continuación, se incluyen sugerencias adicionales para que tu app resulte responsiva:
Si tu app realiza tareas en segundo plano como respuesta a una entrada del usuario, muestra el progreso, por ejemplo, con un elemento ProgressBar en la IU.
En el caso de los juegos, realiza los cálculos de los movimientos en un subproceso de trabajo.
Si tu app tiene una fase de configuración inicial que consume mucho tiempo, considera mostrar una pantalla de presentación o renderizar la vista principal lo más rápido posible.
Indica que la carga está en curso y completa la información de forma asíncrona.
En cualquier caso, recomendamos indicar de alguna manera el progreso para que el usuario no perciba que la app se bloqueó.
Usa herramientas de rendimiento como Perfetto y el Generador de perfiles de CPU para determinar cuellos de botella en la capacidad de respuesta de tu app.
El contenido y las muestras de código que aparecen en esta página están sujetas a las licencias que se describen en la Licencia de Contenido. Java y OpenJDK son marcas registradas de Oracle o sus afiliados.
Última actualización: 2025-07-27 (UTC)
[[["Fácil de comprender","easyToUnderstand","thumb-up"],["Resolvió mi problema","solvedMyProblem","thumb-up"],["Otro","otherUp","thumb-up"]],[["Falta la información que necesito","missingTheInformationINeed","thumb-down"],["Muy complicado o demasiados pasos","tooComplicatedTooManySteps","thumb-down"],["Desactualizado","outOfDate","thumb-down"],["Problema de traducción","translationIssue","thumb-down"],["Problema con las muestras o los códigos","samplesCodeIssue","thumb-down"],["Otro","otherDown","thumb-down"]],["Última actualización: 2025-07-27 (UTC)"],[],[],null,["# Keep your app responsive\n\n**Figure 1.** An ANR dialog displayed to the user.\n\nThis document describes how the Android system determines whether an app isn't\nresponding and shows how to keep your app responsive.\n\nNo matter how well-written your code is, it's possible for your app to still\nfeel sluggish, hang, freeze for significant periods, or take too long to process\ninput. If your app is in the foreground and is unresponsive, the user gets an\nApplication Not Responding (ANR) dialog, as shown in figure 1. The ANR dialog\nlets the user force quit the app. If the app isn't in the foreground, then it's\nsilently stopped. It's critical to design responsiveness into your app to\nminimize ANR dialogs.\n\nANR triggers\n------------\n\nGenerally, the system displays an ANR if an app can't respond to user input on\nthe main thread---also known as the UI thread---preventing the system from\nprocessing incoming user input events.\n\nFor example, an ANR can occur if an app performs a blocking I/O operation, such\nas network access, on the UI thread. Another example is when an app spends too\nmuch time building an elaborate in-memory structure or computing the next move\nin a game on the UI thread.\n\nIn Android, app responsiveness is monitored by the [`ActivityManager`](/reference/android/app/ActivityManager) and\n[`WindowManager`](/reference/android/view/WindowManager) system services. Android displays the ANR dialog for an app\nwhen it detects one of the following conditions:\n\n- No response to an input event---such as key press or screen tap events---within 5 seconds.\n- A [`BroadcastReceiver`](/reference/android/content/BroadcastReceiver) doesn't finish executing within 10 to 20 seconds, for foreground intents. For more information, see [Broadcast receiver timeout](/topic/performance/anrs/diagnose-and-fix-anrs#broadcast-receiver-anr).\n\nAvoid ANRs\n----------\n\nThe following are general tips to avoid ANRs. For more details about diagnosing\nand debugging different types of ANRs, see the other pages in this section.\n\n- Keep the main thread unblocked at all times, and use threads strategically.\n\n - Don't perform blocking or long-running operations on the app's main thread.\n Instead, create a worker thread and do most of the work there.\n\n - Try to minimize any lock contention between the main thread and other\n threads.\n\n - Minimize any non-UI related work on the main thread, such as when handling\n broadcasts or running services. Any method that runs in the UI thread must\n do as little work as possible on that thread. In particular, activities must\n do as little as possible to set up in key lifecycle methods, such as\n `onCreate()` and `onResume()`. See [Background work overview](/guide/background) for more\n information about available solutions for scheduling work on a background\n thread and communicating back with the UI.\n\n - Be careful when sharing thread pools between components. Don't use the same\n threads for potentially long-blocking operations and time-sensitive tasks\n such as broadcast receiving.\n\n | **Note:** Because such threading usually is accomplished at the class level, you can think of responsiveness as a class problem. Compare this with basic code performance, which is a method-level concern.\n- Keep app startup fast. Minimize slow or blocking operations in the app's\n startup code, such as methods run during dagger initialization.\n\n- If you're using `BroadcastReceiver`, consider running broadcast receivers in a\n non-main thread using [`Context.registerReceiver`](/reference/android/content/Context#registerReceiver(android.content.BroadcastReceiver,%20android.content.IntentFilter,%20java.lang.String,%20android.os.Handler,%20int)). For more information,\n see [ANRs in BroadcastReceiver](#anrs-in-broadcast-receiver).\n\n - If you use [`goAsync()`](/reference/android/content/BroadcastReceiver#goAsync()), make sure [`PendingResult.finish`](/reference/kotlin/android/content/BroadcastReceiver.PendingResult?#finish) is called quickly before the ANR timeout.\n\nANRs in BroadcastReceiver\n-------------------------\n\n`BroadcastReceiver` execution time is constrained because broadcast receivers\nare meant to do small, discrete amounts of work in the background, such as\nsaving a setting or registering a [`Notification`](/reference/android/app/Notification). So, as with other\nmethods called in the UI thread, apps must avoid potentially long-running\noperations or calculations in a broadcast receiver. Instead of performing\nlong-running tasks via the UI thread, perform them in the background for later\nexecution. See [Background work overview](/guide/background) for more information about possible\nsolutions.\n\nAnother common issue with `BroadcastReceiver` objects occurs when they execute\ntoo frequently. Frequent background execution can reduce the amount of memory\navailable to other apps. For more information about how to enable and disable\n`BroadcastReceiver` objects efficiently, see [Broadcasts overview](/guide/components/broadcasts).\n| **Tip:** You can use [`StrictMode`](/reference/android/os/StrictMode) to help find potentially lengthy operations such as network or database operations that you might accidentally be doing on your main thread.\n\nReinforce responsiveness\n------------------------\n\nGenerally, 100 to 200ms is the threshold beyond which users perceive slowness in\nan app. Here are additional tips for making your app seem responsive to users:\n\n- If your app is doing work in the background in response to user input, show\n that progress is being made, such as with a [`ProgressBar`](/reference/android/widget/ProgressBar) in your UI.\n\n- For games specifically, do calculations for moves in a worker thread.\n\n- If your app has a time-consuming initial setup phase, consider showing a\n [splash screen](/develop/ui/views/launch/splash-screen) or rendering the main view as quickly as possible.\n Indicate that loading is in progress and fill the information asynchronously.\n In either case, we recommend indicating somehow that progress is being made,\n so that the user doesn't perceive that the app is frozen.\n\n- Use performance tools such as [Perfetto](/topic/performance/tracing) and [CPU Profiler](/studio/profile/cpu-profiler) to\n determine bottlenecks in your app's responsiveness."]]