ANR in Android: cos’è, cause e metodi di risoluzione

Autore: IT Sectr Pubblicato: 2026-07-28 Tempo di lettura: 9 min

ANR (Application Not Responding) è una notifica di sistema in Android che appare quando un’app non risponde all’input entro 5 secondi. A differenza di glitch (errori logici senza blocco dell’interfaccia) e lag (rallentamento senza arresto completo), l’ANR è un errore critico registrato dal sistema operativo: Android mostra un dialogo “L’app non risponde” con l’opzione di chiudere o attendere. Secondo Android Vitals Documentation, le app con un tasso di ANR superiore allo 0,5% ricevono una valutazione più bassa su Google Play e possono essere nascoste dai consigli. La diagnosi include l’analisi di /data/anr/traces.txt, l’uso di StrictMode e la profilazione del thread principale.

Punti chiave

  • ANR — una notifica di sistema in Android quando il thread principale viene bloccato per più di 5 secondi, portando al dialogo “L’app non risponde”
  • Cause principali — blocco del thread principale (BroadcastReceiver, Service), deadlock tra thread, operazione lunga in ContentProvider
  • Diagnosi — analisi di /data/anr/traces.txt, Android Studio Profiler, Firebase Performance Monitoring
  • Risoluzione — scaricare compiti su WorkManager, usare Kotlin Coroutines con Dispatchers.IO, StrictMode per rilevamento precoce
  • Prevenzione — limitare il tempo di BroadcastReceiver a 10 secondi, Service a 20 secondi, ContentProvider a 15 secondi

Cos’è ANR in Android

ANR (Application Not Responding) è un meccanismo di protezione dell’utente in Android che si attiva quando l’app smette di rispondere all’input. Il sistema tiene traccia del tempo di elaborazione degli eventi: se BroadcastReceiver non completa onReceive entro 10 secondi, Service non torna da onCreate entro 20 secondi, o ContentProvider non risponde entro 15 secondi — Android genera un ANR.

Come appare ANR all’utente

Quando si verifica un ANR, Android mostra un dialogo di sistema sopra tutte le finestre: “L’app non risponde. Chiudere o attendere?” L’utente può chiudere l’app o attendere il suo ripristino. Se gli ANR si verificano frequentemente, l’utente disinstalla l’app. Google Play considera il tasso di ANR — la percentuale di sessioni con ANR — nei suoi algoritmi di classificazione.

Differenza tra ANR e blocchi su iOS

iOS non ha un equivalente di ANR con un dialogo di sistema. Invece, Apple usa Watchdog, che termina il processo con codice di uscita 0x8badf00d. L’utente non vede un dialogo — l’app si chiude semplicemente alla schermata home. Questo rende l’ANR su Android più visibile per l’utente, ma dà al sistema più informazioni diagnostiche.

Cause principali di ANR

L’ANR si verifica quando il sistema tiene traccia di un timeout per uno dei quattro tipi di componenti. Ogni componente ha il proprio limite di tempo.

Blocco in BroadcastReceiver

BroadcastReceiver viene eseguito nel thread principale. Se onReceive avvia una richiesta di rete sincrona, una scrittura lunga nel database, o attende un blocco — si verifica un ANR entro 10 secondi. Soluzione: usa goAsync() e WorkManager per l’elaborazione in background. Uno scenario tipico è ricevere una notifica Push da FCM e salvarla in modo sincrono in Room.

Operazione lunga in Service

Service.onCreate e Service.onStartCommand hanno un limite di 20 secondi. Se il servizio avvia un’inizializzazione pesante (caricamento librerie, lettura configurazione dalla rete) nel thread principale — l’ANR è inevitabile. Usa IntentService (obsoleto) o WorkManager per un’esecuzione garantita in background.

ContentProvider con inizializzazione lenta

ContentProvider.onCreate viene eseguito prima di Application.onCreate e ha un limite di 15 secondi. Se il provider esegue una migrazione del database, carica dizionari, o inizializza SDK dalla rete — questo causa ANR all’avvio dell’app. Soluzione: inizializzazione pigra, scaricare operazioni pesanti su WorkManager.

  • BroadcastReceiver — 10 secondi per onReceive; usa goAsync() per l’elaborazione in background
  • Service — 20 secondi per onCreate/onStartCommand; usa WorkManager o CoroutineWorker
  • ContentProvider — 15 secondi per onCreate; sposta l’inizializzazione in Application.onCreate con avvio ritardato
  • Thread UI — 5 secondi senza elaborare eventi; qualsiasi blocco superiore a 5 secondi attiva ANR

Come diagnosticare ANR

Android fornisce diversi strumenti per l’analisi degli ANR: dai log di sistema alle librerie specializzate.

Analisi di traces.txt

A ogni ANR, Android salva il file /data/anr/traces.txt con un dump dello stack di tutti i thread dell’app. Trova il thread “main” — l’ultimo metodo nello stack indica la causa. Pattern tipici: Thread.sleep(), InputStream.read(), BinderProxy.transact(). Per estrarre il file dal dispositivo, usa adb con privilegi di superutente.

Firebase Crashlytics con report ANR

Firebase Crashlytics raccoglie automaticamente gli ANR e li mostra nella dashboard con tracce. Per Android 11+, i report ANR arrivano con lo stack completo del thread principale. L’integrazione richiede l’aggiunta di una dipendenza e l’inizializzazione di FirebaseApp in Application.onCreate.

Android Studio Profiler con tracciamento thread

CPU Profiler in Android Studio permette di registrare tracce dell’app e vedere quali metodi consumano tempo CPU. Abilita “Record with method traces” e riproduci lo scenario che causa l’ANR. La timeline mostrerà quali metodi erano in esecuzione nel thread principale al momento del blocco.

Esempio di integrazione di Firebase Crashlytics per la raccolta ANR su Android:

kotlin
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        FirebaseApp.initializeApp(this)
        FirebaseCrashlytics.getInstance()
            .setCrashlyticsCollectionEnabled(true)
        StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
            .detectAll()
            .penaltyLog()
            .build())
    }
}

Metodi per risolvere ANR

Risolvere ANR significa principalmente spostare tutte le operazioni lunghe dal thread principale ai thread in background. Vediamo tecniche specifiche per ogni tipo di componente.

Uso di WorkManager per compiti in background

WorkManager è la soluzione raccomandata da Google per il lavoro in background. Garantisce l’esecuzione del compito in un thread in background considerando lo stato del dispositivo. A differenza di Service, WorkManager non blocca il thread principale ed è resiliente ai riavvii dell’app. Per BroadcastReceiver, usa goAsync() e passa il PendingResult a WorkManager.

Kotlin Coroutines con dispatcher appropriati

Esegui tutte le richieste di rete, le operazioni del database e l’I/O dei file con Dispatchers.IO. Il thread principale dovrebbe solo aggiornare l’interfaccia. Usa viewModelScope per la cancellazione automatica delle coroutine quando l’Activity viene distrutta. Evita runBlocking() in qualsiasi contesto — blocca in modo sincrono il thread corrente.

Inizializzazione pigra di ContentProvider

Se ContentProvider esegue un’inizializzazione lenta, usa un meccanismo di caricamento pigro: crea un provider che restituisca i dati immediatamente e avvia l’inizializzazione pesante tramite WorkManager con un ritardo. Questo previene ANR all’avvio dell’app, quando il sistema è più sensibile ai ritardi.

Esempio di uso corretto di BroadcastReceiver con goAsync in Android:

kotlin
class FcmReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        val pendingResult = goAsync()
        WorkManager.getInstance(context!!)
            .enqueue(OneTimeWorkRequest.from(NotificationWorker::class.java))
        pendingResult.finish()
    }
}

Prevenzione di ANR nello sviluppo

Il modo migliore per combattere gli ANR è prevenirli durante lo sviluppo attraverso strumenti e decisioni architetturali.

StrictMode per rilevare blocchi del thread principale

StrictMode con le politiche detectNetwork() e detectDiskReads()/detectDiskWrites() abilitate identifica potenziali ANR durante lo sviluppo. Nelle build Debug, imposta penaltyDeath — qualsiasi violazione causerà un crash immediato e lo sviluppatore vedrà il problema prima del commit.

Firebase Performance Monitoring per metriche di produzione

Firebase Performance tiene traccia del tempo di esecuzione delle operazioni chiave e mostra quali scenari superano la soglia ANR. Imposta tracce personalizzate per ogni schermata e richiesta di rete. Se il tempo di esecuzione supera i 3 secondi — è un potenziale ANR che richiede ottimizzazione.

Test con latenza di rete e disco

Simula condizioni lente: limita la velocità della rete usando Network Link Conditioner su iOS o Android Emulator. Rallenta la lettura del disco tramite emulazione di memoria lenta. ANR spesso si manifesta proprio in queste condizioni; sui dispositivi di sviluppo veloci sono invisibili.

  • BroadcastReceiver — usa sempre goAsync() per elaborazione superiore a 1 secondo
  • Service — sostituisci con WorkManager o CoroutineWorker con un dispatcher in background
  • ContentProvider — evita rete e database in onCreate, usa lazy-init con WorkManager
  • Thread UI — StrictMode con penaltyDeath in Debug, Firebase Performance per il monitoraggio in produzione

Domande frequenti

Perché ANR si verifica su Android ma non su iOS?

Android tiene traccia esplicitamente del tempo di elaborazione degli eventi sul thread principale e mostra un dialogo ANR. iOS usa Watchdog, che chiude forzatamente l’app quando si blocca per più di 10–20 secondi. ANR è una caratteristica dell’architettura Android dove diversi componenti (BroadcastReceiver, Service) hanno timeout rigorosi.

Come trovare traces.txt su un dispositivo senza root?

Su Android 11+ puoi ottenere il dump ANR tramite adb shell dumpsys dropbox --print data_app_anr. Su Android 10 e precedenti, senza accesso root a /data/anr/traces.txt. Usa Firebase Crashlytics — raccoglie automaticamente i report ANR per Android 11+.

Quale tasso di ANR è considerato accettabile?

Google Play raccomanda un tasso di ANR inferiore allo 0,5% — non più di 5 ANR ogni 1000 sessioni. Un’app con tasso superiore all’1% riceve un avviso in Google Play Console e può essere nascosta dai consigli. Idealmente, il tasso di ANR dovrebbe essere inferiore allo 0,1%.

Una coroutine può causare ANR?

Una coroutine di per sé non blocca il thread. Ma se all’interno di una coroutine esegui runBlocking sul thread principale o la coroutine viene lanciata con Dispatchers.Main ed esegue una lunga operazione CPU — questo causerà ANR. Usa Dispatchers.IO per I/O e Dispatchers.Default per i calcoli.

Come testare ANR nell’emulatore?

Usa Android Emulator con un profilo “Slow Network” o scrivi un test che chiami Thread.sleep(6000) sul thread principale. Avvia l’app tramite Debug e dopo 5 secondi vedrai il dialogo ANR. Verifica che logcat mostri un record ANR con traccia.

Riepilogo

  • ANR — una notifica di sistema in Android quando il thread principale viene bloccato per più di 5 secondi o vengono superati i timeout dei componenti
  • Timeout: BroadcastReceiver — 10 s, Service — 20 s, ContentProvider — 15 s, UI — 5 s
  • Diagnosi — /data/anr/traces.txt, Firebase Crashlytics, CPU Profiler in Android Studio
  • Risoluzione — WorkManager, goAsync(), Kotlin Coroutines con Dispatchers.IO, inizializzazione pigra di ContentProvider
  • Prevenzione — StrictMode con penaltyDeath, Firebase Performance Monitoring, test con latenza di rete
  • Google Play raccomanda tasso ANR < 0,5%; con tasso > 1% l’app subisce restrizioni di visibilità
  • Raccomandazione: configura Firebase Crashlytics e Performance per la raccolta ANR in produzione e imposta avvisi quando la soglia supera lo 0,3%

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche