ANR (Application Not Responding) é uma notificação do sistema Android que aparece quando um aplicativo para de responder à entrada do usuário por mais de 5 segundos. De acordo com Android Developers, a principal causa são operações longas na thread principal que bloqueiam o processamento de toques e a renderização da interface. Compreender os mecanismos de ANR é essencial para todo desenvolvedor Android criar aplicativos responsivos.
Principais pontos
ANR (Application Not Responding) é uma caixa de diálogo do sistema operacional Android que aparece quando um aplicativo para de responder à entrada do usuário. O sistema rastreia o tempo de processamento de eventos através do InputDispatcher: se um toque ou pressionamento de botão não for manipulado em 5 segundos, o Android mostra um diálogo oferecendo fechar ou aguardar o aplicativo.
O mecanismo ANR protege a experiência do usuário de aplicativos congelados. O Android não permite que um aplicativo bloqueie todo o sistema — ao contrário de sistemas operacionais de desktop, a plataforma móvel limita forçosamente o tempo de processamento de eventos. BroadcastReceiver tem um limite de 10 segundos, e um serviço em primeiro plano tem 20 segundos.
ANR NÃO é uma exceção no código — é um mecanismo do sistema no nível de processos Linux. O Android envia um sinal SIGQUIT ao processo, após o qual o sistema salva a pilha de chamadas de todas as threads no arquivo traces.txt. O desenvolvedor não recebe ANR como uma exceção catch, mas como um relatório após a reinicialização do aplicativo. No Android 11+, a API ApplicationExitInfo permite obter programaticamente a razão da terminação do processo, incluindo ANR — isso simplifica a coleta de estatísticas sem necessidade de análise manual de traces.txt.
Cinco categorias de operações consistentemente levam a ANR em aplicativos Android. Cada uma delas bloqueia a thread principal, impedindo o sistema de processar eventos de entrada e redesenho de tela.
Requisições HTTP síncronas executadas na thread de UI são a causa mais comum de ANR entre desenvolvedores iniciantes. Mesmo uma requisição rápida a um servidor pode levar de 1 a 3 segundos, e com uma conexão ruim — 30 segundos ou mais. O Android proíbe explicitamente operações de rede na thread principal a partir da API 11, lançando NetworkOnMainThreadException.
Use Coroutines ou RxJava para chamadas assíncronas. Corrotinas com o dispatcher Dispatchers.IO executam a requisição em uma thread de fundo e passam o resultado para a thread principal via Dispatchers.Main. Isso elimina completamente o bloqueio da thread de UI por operações de rede.
fun fetchUserData() {
CoroutineScope(Dispatchers.Main).launch {
val result = withContext(Dispatchers.IO) {
api.getUserData() // operação em segundo plano
}
updateUI(result) // resultado na thread principal
}
}
Processar grandes arrays de dados, analisar JSON ou XML, trabalhar com bitmaps diretamente na thread principal — a segunda causa mais frequente de ANR. Mesmo 300 milissegundos de trabalho contínuo da thread de UI sem retornar ao loop de eventos causa um atraso notável na renderização, e o limite de 5 segundos é registrado como ANR.
WorkManager e serviços em segundo plano são projetados para mover cálculos pesados para fora da thread principal. Use AsyncTask (obsoleto), ListenableFuture ou Kotlin Flow para passar dados em blocos sem bloquear a UI.
Um Deadlock ocorre quando duas threads seguram locks e esperam uma pela outra. Se uma das threads é a thread principal, o sistema registra ANR exatamente após 5 segundos. Thread.join(), CountDownLatch.await() e blocos synchronized chamados da thread de UI carregam risco de bloqueio.
Evite qualquer operação bloqueante na thread principal. Em vez de synchronized, use ConcurrentHashMap; em vez de Thread.join() — corrotinas com async/await. Esta regra se aplica a qualquer linguagem no Android: Java, Kotlin ou C++ via JNI.
BroadcastReceiver é executado na thread principal por padrão. Se onReceive() estiver ocupado por mais de 10 segundos, o Android mostra ANR. Carregar dados de um banco de dados ou rede dentro de onReceive é um caminho garantido para o congelamento.
Use goAsync() dentro de BroadcastReceiver para mudar para uma thread de fundo, ou registerReceiver com getBackgroundBroadcastReceiver(). Isso permite manipular eventos sem bloquear a UI.
Consultas pesadas ao ContentProvider ou trabalho direto com SQLite na thread de UI — uma causa menos óbvia mas comum de ANR. Durante a migração do banco de dados ou inserção em massa de milhares de registros, o tempo de execução pode exceder o limite de 5 segundos.
Mova todas as operações de banco de dados para threads de fundo usando Room com funções suspend. O Room verifica automaticamente se a consulta não está sendo executada na thread principal e lança uma exceção se violada.
Diagnosticar ANR difere de depurar exceções normais — você não pode capturar ANR em um bloco try-catch. A principal fonte de informação é o arquivo traces.txt, que o Android cria no momento do congelamento.
traces.txt contém a pilha de chamadas de todas as threads do aplicativo no momento do ANR. Para ler o arquivo de um dispositivo real, execute o comando adb bugreport, que coleta um relatório completo do sistema incluindo todos os ANRs recentes. Para um emulador, o arquivo está disponível em /data/anr/traces.txt. A pilha de chamadas mostra qual método estava sendo executado na thread principal no momento do bloqueio.
adb bugreport bugreport.zip
unzip -p bugreport.zip "*traces*" > traces.txt
Google Play Console fornece a seção ANR & Crash com relatórios agregados e frequências de erro. Para cada ANR, a pilha de chamadas e estatísticas do dispositivo são mostradas: modelo, versão do Android, região. Isso permite identificar ANRs que dependem de dispositivos ou versões de sistema específicos.
Android Studio desde 2021 inclui ANR Watchdog no profiler. Ele grava automaticamente dumps de thread se a thread principal não responder por mais de um tempo limite. A ferramenta mostra uma linha do tempo de eventos: quais operações foram iniciadas, quais métodos foram executados e em que estágio o bloqueio ocorreu.
A prevenção de ANR é construída em uma regra fundamental: a thread principal deve apenas manipular eventos de UI. Qualquer operação com mais de 16 milissegundos (tempo de um quadro) deve ser executada em uma thread de fundo.
StrictMode é uma ferramenta integrada do Android para detectar potenciais ANRs durante o desenvolvimento. Ative-o em Application.onCreate() com flags para operações de disco e rede. Quando violado, StrictMode lança uma exceção ou escreve no logcat.
if (BuildConfig.DEBUG) {
StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyLog()
.build()
.let { StrictMode.setThreadPolicy(it) }
}
Kotlin Coroutines — a forma padrão de trabalho assíncrono em aplicativos Android modernos. A abordagem principal: operações de E/S executam em Dispatchers.IO, o resultado é passado para Dispatchers.Main para atualizações de UI. Para cenários semelhantes a Flow, use Dispatchers.Default para tarefas intensivas de CPU.
RxJava continua popular em projetos legados. subscribeOn(Schedulers.io()) e observeOn(AndroidSchedulers.mainThread()) — o conjunto mínimo para prevenir ANR. A regra principal é a mesma: nenhum Observable ou Flowable deve emitir dados da thread principal.
Firebase Crashlytics desde a versão SDK 18.4.0 suporta monitoramento de ANR nativamente. Para Android 11+, o Crashlytics usa a API do sistema ApplicationExitInfo, que fornece a razão exata da terminação: ANR, Crash, ou eliminação pelo sistema. Ative chaves personalizadas com parâmetros de tela e estado para análise contextual.
Cinco ferramentas cobrem todos os estágios de trabalho com ANR: desde a depuração em uma estação de trabalho até o monitoramento em produção. Cada ferramenta resolve sua própria tarefa e fornece dados para diferentes cenários.
| Ferramenta | Propósito | Formato de dados |
|---|---|---|
| StrictMode | Detecção durante o desenvolvimento | Logcat / Exception |
| ANR Watchdog (Android Studio) | Rastreamento em tempo real | Thread dump + timeline |
| Google Play Console | Estatísticas agregadas | ANR rate + stack traces |
| Firebase Crashlytics | Monitoramento em produção | ApplicationExitInfo |
| adb bugreport | Relatório completo do sistema | traces.txt + logcat + dmesg |
Cada ferramenta tem seu próprio nicho: StrictMode detecta violações óbvias em estágios iniciais, Crashlytics mostra a frequência real de ANR entre os usuários, e adb bugreport fornece a imagem mais completa para casos complexos. Combine-os para cobertura total.
Firebase Performance rastreia o tempo de resposta da thread de UI e cria automaticamente traces para operações suspeitamente longas. Se a thread principal bloquear por mais de 500 ms, o Performance registra um trace personalizado com o nome do método culpado. Isso permite detectar cenários de ANR sem envolvimento do usuário e antes que se tornem críticos.
A integração com Firebase Crashlytics fornece uma imagem completa: o Performance mostra lentidões antes do ANR, e o Crashlytics mostra o congelamento em si. Configure alertas no Firebase Console para taxa de ANR acima de 0.1%, e você receberá notificações sobre novos problemas antes de reclamações em massa de usuários.
Perguntas frequentes
ANR é um congelamento onde o aplicativo não responde mas permanece na memória. Crash é uma terminação anormal completa com saída do processo. ANR pode ser “sobrevivido” se o sistema ou usuário aguardar uma resposta, enquanto Crash sempre termina o aplicativo.
Não. ANR não é uma exceção Java/Kotlin, mas um sinal do sistema no nível de processos (SIGQUIT). Um desenvolvedor não pode manipulá-lo no código do aplicativo. A única forma de responder a ANR é analisar relatórios após a reinicialização.
O desempenho do dispositivo, versão do Android, carga de CPU e número de processos em segundo plano afetam a probabilidade de ANR. Em dispositivos fracos, a mesma operação pode levar de 2 a 3 vezes mais tempo, excedendo o limite de 5 segundos.
10 segundos para um BroadcastReceiver normal em onReceive(). Para serviços em primeiro plano, o limite é de 20 segundos, e para ContentProvider — não há um limite explícito, mas bloquear a thread principal por mais de 5 segundos ainda causa ANR.
Ative StrictMode em todas as compilações de depuração, adicione monitoramento via Firebase Crashlytics e use adb bugreport quando o ANR ocorrer. ANRs irregulares geralmente estão relacionados a condições de corrida ou estados de rede específicos.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também