Diagnosticar e corrigir ANRs

Quando a linha de execução de interface de um app Android é bloqueada por muito tempo, o sistema envia um erro "O app não está respondendo" (ANR). Esta página descreve os diferentes tipos de ANR, como diagnosticá-los e sugestões para corrigi-los. Todos os períodos de tempo limite padrão listados são para dispositivos AOSP e Pixel e podem variar de acordo com o OEM.

Ao determinar a causa dos ANRs, vale a pena distinguir entre problemas do sistema e do app.

Quando o sistema está em mau estado, os problemas abaixo podem causar ANRs:

  • Problemas temporários no servidor do sistema costumam causar lentidão nas chamadas de vinculação que deveriam ser rápidas.
  • Problemas com o servidor do sistema e sobrecarga do dispositivo fazem com que as linhas de execução do app não sejam agendadas.

Uma boa maneira de distinguir entre problemas do sistema e do app é usar rastros do Perfetto (link em inglês), se disponíveis:

  • Confira se a linha de execução principal do app está agendada na faixa do estado da linha de execução no Perfetto para saber se ela está em execução ou pode ser executada.
  • Confira se há problemas nas linhas de execução system_server, por exemplo, contenção de bloqueio.
  • Para chamadas de vinculação lentas, observe a linha de execução de resposta, se houver, para verificar por que ela está lenta.

Tempo limite do envio de entradas

ANRs de envio de entradas ocorrem quando a linha de execução principal do app não responde a tempo a um evento de entrada, por exemplo, deslizar ou pressionar uma tecla. Como o app está em primeiro plano quando o tempo limite de envio de entradas é alcançado, ele quase sempre fica visível para o usuário, e é muito importante mitigar esses problemas.

Período de tempo limite padrão: cinco segundos.

Os ANRs no envio de entradas geralmente são causados por problemas na linha de execução principal. Se a linha de execução principal estiver bloqueada enquanto espera adquirir um bloqueio, a linha de execução detentora também pode estar envolvida.

Para evitar ANRs de envio de entradas, siga estas práticas recomendadas:

  • Não execute operações de bloqueio ou de longa duração na linha de execução principal. Uma opção é usar o StrictMode para capturar atividades acidentais na linha de execução principal.
  • Minimize a contenção de bloqueio entre a linha de execução principal e as outras.
  • Minimize qualquer trabalho não esteja relacionado à interface na linha de execução principal, por exemplo, ao processar transmissões ou executar serviços.

Causas comuns

Confira algumas causas comuns e correções sugeridas para ANRs de envio de entradas.

Causa O que acontece Correções sugeridas
Chamada de vinculação lenta A linha de execução principal faz uma longa chamada síncrona de vinculação. Mova a chamada para fora da linha de execução principal ou tente otimizar a chamada, se você for o proprietário da API.
Muitas chamadas de vinculação consecutivas A linha de execução principal faz muitas chamadas síncronas de vinculação consecutivas. Não execute chamadas de vinculação em uma repetição curta.
Bloqueio de E/S A linha de execução principal faz chamadas de E/S de bloqueio, por exemplo, acesso ao banco de dados ou à rede. Remova todas as E/S de bloqueio da linha de execução principal.
Contenção de bloqueio A linha de execução principal está bloqueada enquanto espera adquirir um bloqueio. Reduza a contenção de bloqueio entre a linha de execução principal e as outras. Otimize o código lento na outra linha de execução.
Frame caro Renderização excessiva em um único frame, causando instabilidade grave. Faça menos trabalho renderizando o frame. Não use algoritmos n2. Use componentes eficientes para operações como de rolagem ou paginação, por exemplo, a biblioteca Paging do Jetpack.
Bloqueada por outro componente Um componente diferente, por exemplo, um broadcast receiver, está em execução e bloqueando a linha de execução principal. Remova o máximo possível de trabalhos que não sejam da interface da linha de execução principal. Execute broadcast receivers em uma linha de execução diferente.
Suspensão de GPU A suspensão de GPU é um problema de sistema ou hardware que faz com que a renderização seja bloqueada, causando um ANR de envio de entradas. Em geral, não há correções a serem feitas no app nesses casos. Se possível, entre em contato com a equipe de hardware para resolver o problema.

Como depurar

Para começar a depuração, observe a assinatura do cluster de ANR no Google Play Console ou no Firebase Crashlytics. O cluster normalmente contém os principais frames suspeitos de causar o ANR.

O fluxograma abaixo mostra como determinar a causa de um ANR de envio de tempo limite de entradas.

Figura 1. Como depurar um ANR de envio de entradas.

A execução de métricas pode detectar e ajudar a depurar algumas dessas causas comuns de ANRs. Por exemplo, se as métricas detectarem que um ANR ocorreu devido à contenção de bloqueio, elas poderão resumir o problema e a correção recomendada na seção Insights do ANR.

Figura 2. Métricas de detecção de ANRs.

Nenhuma janela em foco

Embora eventos como toque sejam enviados diretamente à janela relevante com base em testes de hit, eventos como pressionamento de teclas precisam de um destino. Esse destino é conhecido como janela em foco. Há apenas uma janela em foco por tela, e geralmente é a janela com que o usuário está interagindo no momento. Se uma janela em foco não for encontrada, a entrada vai gerar um ANR de nenhuma janela em foco. Um ANR de nenhuma janela em foco é um tipo de ANR de envio de entradas.

Período de tempo limite padrão: cinco segundos.

Causas comuns

Os ANRs de nenhuma janela em foco são causados por um destes problemas:

  • O app está fazendo muito trabalho e demora demais para renderizar o primeiro frame.
  • Não é possível focar na janela principal. Se uma janela tiver a flag FLAG_NOT_FOCUSABLE, o usuário não poderá enviar eventos de tecla ou botão para ela.

Kotlin

override fun onCreate(savedInstanceState: Bundle) {
  super.onCreate(savedInstanceState)
  setContentView(R.layout.activity_main)
  window.addFlags(WindowManager.LayoutParams.FLAG_FLAG_NOT_FOCUSABLE)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
}

Tempo limite de um broadcast receiver

Um ANR de broadcast receiver ocorre quando um broadcast receiver não processa uma transmissão a tempo. Para broadcast receivers síncronos ou que não chamam goAsync(), o tempo limite significa que onReceive() não foi concluído em um período de dois minutos. Para receptores assíncronos ou que chamam goAsync(), o tempo limite significa que PendingResult.finish() não foi chamado a tempo.

Os ANRs de broadcast receiver geralmente acontecem nestas linhas de execução:

  • Linha de execução principal, se o problema for a inicialização lenta do app.
  • Linha de execução que executa o broadcast receiver, se o problema for um código onReceive() lento.
  • Linhas de execução de transmissão do worker, se o problema for um código de transmissão goAsync() lento.

Para evitar ANRs de broadcast receiver, siga estas práticas recomendadas:

  • Verifique se a inicialização do app é rápida, já que ela será contada no tempo limite do ANR se o app for iniciado para processar a transmissão.
  • Se o método goAsync() for usado, confira se PendingResult.finish() é chamado rapidamente. Ele está sujeito ao mesmo tempo limite de ANRs que os broadcast receivers síncronos.
  • Se o método goAsync() for usado, confira se as linhas de execução de worker não estão sendo compartilhadas com outras operações de longa duração ou bloqueio.
  • Uma opção é usar registerReceiver() para executar broadcast receivers em uma linha de execução que não seja a principal para evitar o bloqueio do código da interface executado na linha de execução principal.

Períodos de tempo limite

Os períodos de tempo limite de broadcast receiver dependem da definição da flag de intent em primeiro plano e da versão da plataforma.

Tipo de intent Android 13 e versões anteriores Android 14 e versões mais recentes

Intent de prioridade em primeiro plano

(FLAG_RECEIVER_FOREGROUND definida)

10 segundos

10 a 20 segundos, dependendo se o processo está com pouco acesso à CPU ou não

Intent de prioridade de segundo plano

(FLAG_RECEIVER_FOREGROUND não definida)

60 segundos

60 a 120 segundos, dependendo se o processo está com pouco acesso à CPU ou não

Para saber se a flag FLAG_RECEIVER_FOREGROUND está definida, procure "flg=" no conteúdo do ANR e confira se 0x10000000 aparece. Se esse bit estiver definido, significa que a FLAG_RECEIVER_FOREGROUND está definida na intent, e, portanto, o tempo limite será menor.

Exemplo de conteúdo de ANR com tempo limite de transmissão curto (10 a 20 segundos):

Broadcast of Intent { act=android.inent.action.SCREEN_ON flg=0x50200010 }

Exemplo de conteúdo de ANR com tempo limite de transmissão longo (60 a 120 segundos):

Broadcast of Intent { act=android.intent.action.TIME_SET flg=0x25200010 }

Como os tempos de transmissão são medidos

A medição da duração da transmissão começa quando a transmissão é despachada do system_server para o app e acaba quando o app termina de processar a transmissão. Se o processo do app ainda não estiver em execução, ele também precisará fazer uma inicialização a frio dentro do tempo limite do ANR. Uma inicialização lenta do app pode resultar em ANRs de broadcast receiver.

A figura abaixo ilustra o alinhamento da linha do tempo do ANR de broadcast receiver com determinados processos do app.

Figura 3. Linha do tempo de um ANR de broadcast receiver.

A medição do tempo limite do ANR acaba quando o receptor termina de processar a transmissão. O momento exato em que isso acontece depende se o receptor é síncrono ou assíncrono.

  • Para receptores síncronos, a medição é interrompida quando onReceive() é retornado.
  • Para receptores assíncronos, a medição é interrompida quando PendingResult.finish() é chamado.
Figura 4. Endpoints de medição de tempo limite de ANRs para receptores síncronos e assíncronos.

Causas comuns

Confira algumas causas comuns e correções sugeridas para ANRs de broadcast receiver.

Causa Aplica-se a O que aconteceu Correção sugerida
Inicialização lenta do app Todos os receptores O app demorou muito para fazer uma inicialização a frio. Otimize a inicialização lenta do app.
onReceive() não agendado Todos os receptores A linha de execução de broadcast receiver estava ocupada fazendo outro trabalho e não pôde iniciar o método onReceive(). Não execute tarefas de longa duração na linha de execução receptora (ou mova o receptor para uma linha de execução dedicada).
onReceive() lento Todos os receptores, mas principalmente os síncronos O método onReceive() foi iniciado, mas estava bloqueado ou lento e não foi concluído a tempo. Otimize o código lento do receptor.
Tarefas de receptor assíncrono não agendadas Receptores goAsync() O método onReceive() tentou executar o trabalho em um pool de linhas de execução de worker bloqueado, então o trabalho não foi iniciado. Otimize chamadas lentas ou de bloqueio ou use linhas de execução diferentes para workers de transmissão em vez de outras tarefas de longa duração.
Workers lentos ou bloqueados Receptores goAsync() Ocorreu uma operação de bloqueio ou lentidão em algum lugar do pool de linhas de execução de worker durante o processamento da transmissão, fazendo com que PendingResult.finish não fosse chamado a tempo. Otimize o código lento do receptor async.
Esqueceu de chamar PendingResult.finish Receptores goAsync() A chamada para finish() não está no caminho do código. finish() precisa ser chamado sempre.

Como depurar

Com base na assinatura do cluster e no relatório de ANRs, é possível localizar a linha de execução em que o receptor é executado e, em seguida, o código específico que está ausente ou sendo executado lentamente.

O fluxograma abaixo mostra como determinar a causa de um ANR de broadcast receiver.

Figura 5. Como depurar um ANR de broadcast receiver.

Encontre o código receptor

O Google Play Console mostra a classe do receptor e a intent de transmissão na assinatura do ANR. Procure o seguinte:

  • cmp=<receiver class>
  • act=<broadcast_intent>

Confira um exemplo de assinatura de ANRs de broadcast receiver:

com.example.app.MyClass.myMethod
Broadcast of Intent { act=android.accounts.LOGIN_ACCOUNTS_CHANGED
cmp=com.example.app/com.example.app.MyAccountReceiver }

Encontre a linha de execução do método onReceive()

Se você estiver usando Context.registerReceiver para especificar um gerenciador personalizado, ele será a linha de execução que executa esse gerenciador. Caso contrário, será a linha de execução principal.

Exemplo: tarefas do receptor assíncrono não agendadas

Esta seção mostra um exemplo de como depurar um ANR de broadcast receiver.

Digamos que a assinatura ANR tenha seja parecida com esta:

com.example.app.MyClass.myMethod
Broadcast of Intent {
act=android.accounts.LOG_ACCOUNTS_CHANGED cmp=com.example.app/com.example.app.MyReceiver }

Com base na assinatura, parece que a intent de transmissão é android.accounts.LOG_ACCOUNTS_CHANGED e que a classe do receptor é com.example.app.MyReceiver.

No código do receptor, você pode determinar que o conjunto de linhas de execução "BG Thread [0,1,2,3]" faz o trabalho principal para processar essa transmissão. Analisando os despejos de pilha, é possível observar que todas as quatro linhas de execução em segundo plano (BG) têm o mesmo padrão: elas executam uma chamada de bloqueio, getDataSync. Como todas as linhas de execução em segundo plano estavam ocupadas, a transmissão não foi processada a tempo, o que causou um ANR.

BG Thread #0 (tid=26) Waiting

at jdk.internal.misc.Unsafe.park(Native method:0)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture:563)
at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture:68)
at com.example.app.getDataSync(<MyClass>:152)

...

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
at com.google.android.libraries.concurrent.AndroidExecutorsModule.lambda$withStrictMode$5(AndroidExecutorsModule:451)
at com.google.android.libraries.concurrent.AndroidExecutorsModule$$ExternalSyntheticLambda8.run(AndroidExecutorsModule:1)
at java.lang.Thread.run(Thread.java:1012)
at com.google.android.libraries.concurrent.ManagedPriorityThread.run(ManagedPriorityThread:34)

There are several approaches to fix the issue:

  • Find out why getDataSync is slow and optimize.
  • Don't run getDataSync on all four BG threads.
  • More generally, ensure that the BG thread pool isn't saturated with long-running operations.
  • Use a dedicated thread pool for goAsync worker tasks.
  • Use an unbounded thread pool instead of the bounded BG thread pool

Example: slow app startup

A slow app startup can cause several types of ANRs, especially broadcast receiver and execute service ANRs. The cause of an ANR is likely slow app startup if you see ActivityThread.handleBindApplication in the main thread stacks.

Execute service timeout

An execute service ANR happens when the app's main thread doesn't start a service in time. Specifically, a service doesn't finish executing onCreate() and onStartCommand() or onBind() within the timeout period.

Default timeout period: 20 seconds for foreground service; 200 seconds for background service. The ANR timeout period includes the app cold start, if necessary, and calls to onCreate(), onBind(), or onStartCommand().

To avoid execute service ANRs, follow these general best practices:

  • Make sure that app startup is fast, since it's counted in the ANR timeout if the app is started to run the service component.
  • Make sure that the service's onCreate(), onStartCommand(), and onBind() methods are fast.
  • Avoid running any slow or blocking operations on the main thread from other components; these operations can prevent a service from starting quickly.

Common causes

The following table lists common causes of execute service ANRs and suggested fixes.

Cause What Suggested fix
Slow app startup The app takes too long to perform a cold start. Optimize slow app start.
Slow onCreate(), onStartCommand(), or onBind() The service component's onCreate(), onStartCommand(), or onBind() method takes too long to execute on the main thread. Optimize slow code. Move slow operations off the critical path where possible.
Not scheduled (main thread blocked before onStart()) The app's main thread is blocked by another component before the service can be started. Move other component's work off the main thread. Optimize other component's blocking code.

How to debug

From the cluster signature and ANR report in Google Play Console or Firebase Crashlytics, you can often determine the cause of the ANR based on what the main thread is doing.

The following flow chart describes how to debug an execute service ANR.

Figure 6. How to debug an execute service ANR.

If you've determined that the execute service ANR is actionable, follow these steps to help resolve the issue:

  1. Find the service component class in the ANR signature. In Google Play Console, the service component class is shown in the ANR signature. In the following example ANR details, it's com.example.app/MyService.

    com.google.common.util.concurrent.Uninterruptibles.awaitUninterruptibly
    Executing service com.example.app/com.example.app.MyService
    
  2. Determine whether the slow or block operation is part of app startup, the service component, or elsewhere by checking for the following important function call(s) in the main threads.

    Function call(s) in main thread stacks What it means
    android.app.ActivityThread.handleBindApplication App was starting up, so the ANR was caused by slow app start.

    <ServiceClass>.onCreate()

    [...]

    android.app.ActivityThread.handleCreateService

    Service was being created, so the ANR was likely caused by slow onCreate() code.

    <ServiceClass>.onBind()

    [...]

    android.app.ActivityThread.handleBindService

    Service was being bound, so the ANR was likely caused by slow onBind() code.

    <ServiceClass>.onStartCommand()

    [...]

    android.app.ActivityThread.handleServiceArgs

    Service was being started, so the ANR was likely caused by slow onStartCommand() code.

    For example, if the onStartCommand() method in the MyService class is slow, the main threads will look like this:

    at com.example.app.MyService.onStartCommand(FooService.java:25)
    at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4820)
    at android.app.ActivityThread.-$$Nest$mhandleServiceArgs(unavailable:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2289)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:205)
    at android.os.Looper.loop(Looper.java:294)
    at android.app.ActivityThread.main(ActivityThread.java:8176)
    at java.lang.reflect.Method.invoke(Native method:0)
    

    Se você não encontrar nenhuma das chamadas de função importantes, há algumas outras possibilidades:

    • O serviço está em execução ou sendo encerrado, o que significa que as pilhas estão demoradas demais. Nesse caso, ignore o ANR como um falso positivo.
    • Um componente de app diferente está em execução, por exemplo, um broadcast receiver. Nesse caso, a linha de execução principal provavelmente está bloqueada nesse componente, impedindo que o serviço seja iniciado.
  3. Se você encontrar uma chamada de função principal e puder determinar onde o ANR está ocorrendo, verifique o restante das pilhas de linha de execução principais para encontrar a operação lenta e otimizá-la ou removê-la do caminho crítico.

  4. Para mais informações sobre serviços, consulte estas páginas:

    O provedor de conteúdo não está respondendo

    Um ANR de provedor de conteúdo acontece quando um provedor de conteúdo remoto leva mais tempo do que o tempo limite para responder a uma consulta e é encerrado.

    Tempo limite padrão: especificado pelo provedor de conteúdo usando ContentProviderClient.setDetectNotResponding. O tempo limite do ANR inclui o tempo total de execução de uma consulta de provedor do conteúdo remoto, o que inclui a inicialização a frio do app remoto, caso ele ainda não esteja em execução.

    Para evitar ANRs do provedor de conteúdo, siga estas práticas recomendadas:

    • A inicialização do app precisa ser rápida, já que ela será contada no tempo limite do ANR se o app for iniciado para executar o provedor de conteúdo.
    • As consultas do provedor de conteúdo precisam ser rápidas.
    • Não execute muitas chamadas de vinculação de bloqueio simultâneas que possam bloquear todas as linhas de execução de vinculação do app.

    Causas comuns

    A tabela abaixo lista as causas comuns de ANRs do provedor de conteúdo e as correções sugeridas.

    Causa O que acontece Sinal Correção sugerida
    Consulta lenta ao provedor de conteúdo O provedor de conteúdo demora muito para ser executado ou está bloqueado. O frame android.content.ContentProvider$Transport.query está na linha de execução de vinculação. Otimize a consulta do provedor de conteúdo. Descubra o que está bloqueando a linha de execução de vinculação.
    Inicialização lenta do app O app do provedor de conteúdo demora muito para ser iniciado. O frame ActivityThread.handleBindApplication está na linha de execução principal. Otimize a inicialização do app.
    Esgotamento das linhas de execução de vinculação: todas as linhas de execução de vinculação estão ocupadas Todas as linhas de execução de vinculação estão ocupadas atendendo outras solicitações síncronas. Por isso, a chamada de vinculação do provedor de conteúdo não pode ser executada. O app não está sendo iniciado, todas as linhas de execução de vinculação estão ocupadas, e o provedor de conteúdo não está em execução. Reduza a carga nas linhas de execução de vinculação. Ou seja, faça menos chamadas de vinculação de saída síncronas ou realize menos trabalho ao processar chamadas recebidas.

    Como depurar

    Para depurar um ANR do provedor de conteúdo usando a assinatura do cluster e o Relatório de ANR no Google Play Console ou no Firebase Crashlytics, observe o que as linhas de execução principais e de vinculação estão fazendo.

    O fluxograma abaixo descreve como depurar um ANR do provedor de conteúdo:

    Figura 7. Como depurar um ANR de provedor de conteúdo.

    O snippet de código abaixo mostra a aparência da linha de execução de vinculação quando ela é bloqueada por uma consulta lenta do provedor de conteúdo. Nesse caso, a consulta do provedor de conteúdo está aguardando o bloqueio ao abrir um banco de dados.

    binder:11300_2 (tid=13) Blocked
    
    Waiting for osm (0x01ab5df9) held by at com.google.common.base.Suppliers$NonSerializableMemoizingSupplier.get(Suppliers:182)
    at com.example.app.MyClass.blockingGetOpenDatabase(FooClass:171)
    [...]
    at com.example.app.MyContentProvider.query(MyContentProvider.java:915)
    at android.content.ContentProvider$Transport.query(ContentProvider.java:292)
    at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:107)
    at android.os.Binder.execTransactInternal(Binder.java:1339)
    at android.os.Binder.execTransact(Binder.java:1275)
    

    O snippet de código abaixo mostra a aparência da linha de execução principal quando ela é bloqueada devido à inicialização lenta do app. Nesse caso, a inicialização do app é lenta devido à contenção de bloqueio durante a inicialização do Dagger.

    main (tid=1) Blocked
    
    [...]
    at dagger.internal.DoubleCheck.get(DoubleCheck:51)
    - locked 0x0e33cd2c (a qsn)at dagger.internal.SetFactory.get(SetFactory:126)
    at com.myapp.Bar_Factory.get(Bar_Factory:38)
    [...]
    at com.example.app.MyApplication.onCreate(DocsApplication:203)
    at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1316)
    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6991)
    at android.app.ActivityThread.-$$Nest$mhandleBindApplication(unavailable:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2235)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:205)
    at android.os.Looper.loop(Looper.java:294)
    at android.app.ActivityThread.main(ActivityThread.java:8170)
    at java.lang.reflect.Method.invoke(Native method:0)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
    

    Resposta lenta ao job

    Um ANR de resposta lenta de job acontece quando o app demora muito para responder a JobService.onStartJob() ou JobService.onStopJob() ou demora muito para fornecer uma notificação usando JobService.setNotification(). Isso sugere que a linha de execução principal do app está bloqueada fazendo alguma outra coisa.

    Se for um problema com JobService.onStartJob() ou JobService.onStopJob(), confira o que está acontecendo na linha de execução principal. Se for um problema com JobService.setNotification(), chame-o o mais rápido possível. Não realize muito trabalho antes de enviar a notificação.

    ANRs indefinidos

    Às vezes, não está claro por que um ANR está ocorrendo ou não há informações suficientes para depurá-lo na assinatura do cluster e no relatório de ANR. Nesses casos, ainda há algumas etapas que podem ser seguidas para determinar se o ANR é acionável.

    Fila de mensagens inativa ou nativePollOnce

    Se o frame android.os.MessageQueue.nativePollOnce é mostrado nas pilhas, isso geralmente indica que a linha de execução suspeita não responsiva estava inativa e aguardando mensagens de looper. No Google Play Console, os detalhes do ANR ficam assim:

    Native method - android.os.MessageQueue.nativePollOnce
    Executing service com.example.app/com.example.app.MyService
    

    Por exemplo, se a linha de execução principal estiver inativa, as pilhas ficarão assim:

    "main" tid=1 NativeMain threadIdle
    
    #00  pc 0x00000000000d8b38  /apex/com.android.runtime/lib64/bionic/libc.so (__epoll_pwait+8)
    #01  pc 0x0000000000019d88  /system/lib64/libutils.so (android::Looper::pollInner(int)+184)
    #02  pc 0x0000000000019c68  /system/lib64/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+112)
    #03  pc 0x000000000011409c  /system/lib64/libandroid_runtime.so (android::android_os_MessageQueue_nativePollOnce(_JNIEnv*, _jobject*, long, int)+44)
    at android.os.MessageQueue.nativePollOnce (Native method)
    at android.os.MessageQueue.next (MessageQueue.java:339)  at android.os.Looper.loop (Looper.java:208)
    at android.app.ActivityThread.main (ActivityThread.java:8192)
    at java.lang.reflect.Method.invoke (Native method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:626)
    at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1015)
    

    Há vários motivos para a linha de execução suspeita não responder:

    • Despejo de pilha atrasado: A linha de execução extraída durante o curto período entre o acionamento de ANR e as pilhas que estão sendo despejadas. A latência em dispositivos Pixel com o Android 13 é de cerca de 100 ms, mas pode exceder 1 segundo. A latência em dispositivos Pixel com o Android 14 geralmente é menor que 10ms.
    • Atribuição incorreta da linha de execução: A linha de execução usada para criar a assinatura de ANR não era a linha de execução não responsiva que causou o ANR. Nesse caso, tente determinar se o ANR é de um destes tipos:
    • Problema do sistema: O processo não foi agendado devido a uma grande carga do sistema ou a um problema no servidor do sistema.

    Nenhum frame de pilha

    Alguns relatórios de ANR não incluem as pilhas com o ANR, o que significa que o despejo de pilha falhou ao gerar o Relatório de ANR. Há alguns motivos possíveis para a falta de frames de pilha:

    • A remoção da pilha demora muito e expira.
    • O processo travou ou foi encerrado antes de as pilhas serem preenchidas.
    [...]
    
    --- CriticalEventLog ---
    capacity: 20
    timestamp_ms: 1666030897753
    window_ms: 300000
    
    libdebuggerd_client: failed to read status response from tombstoned: timeout reached?
    
    ----- Waiting Channels: pid 7068 at 2022-10-18 02:21:37.<US_SOCIAL_SECURITY_NUMBER>+0800 -----
    
    [...]
    

    ANRs sem frames de pilha não são acionáveis na assinatura do cluster ou no Relatório de ANR. Para depurar, observe outros clusters do app, já que, se um problema for grande o suficiente, ele geralmente terá o próprio cluster em que os frames de pilha estão presentes. Outra opção é analisar os rastros do Perfetto (link em inglês).

    Problemas conhecidos

    Manter um timer no processo do app para concluir o processamento de transmissão antes do acionamento de ANR pode não funcionar corretamente devido à forma assíncrona em que o sistema monitora ANRs.