Esegui il debug della tua app per Android in base ai tag ANR nella dashboard di Crashlytics

Gli errori L'applicazione non risponde (ANR) vengono attivati quando il thread dell'interfaccia utente dell'applicazione non risponde per più di 5 secondi. Puoi leggere di più sugli errori ANR e sulla loro diagnosi nella documentazione di Android.

Inoltre, Crashlytics può aiutarti a individuare thread specifici con problemi. Analizziamo gli ANR e poi, nella dashboard Crashlytics, tagghiamo i thread applicabili per fornire suggerimenti su come eseguire il debug dell'ANR.

Le sezioni seguenti di questa pagina spiegano il significato di ciascun tag ANR, mostrano un esempio di ANR con quel tag e forniscono una soluzione consigliata per eseguire il debug dell'ANR.

Triggered ANR

Un thread che è stato bloccato per troppo tempo e ha attivato l'ANR è annotato con questo tag Triggered ANR.

Il thread problematico può essere il thread principale dell'app o qualsiasi thread che non risponde. Tuttavia, il thread contrassegnato come Triggered ANR potrebbe o meno essere la causa effettiva dell'ANR. Per fornire informazioni per il debug e la correzione di questi ANR, Crashlytics contrassegna anche tutti gli altri thread coinvolti nell'ANR. Nelle seguenti sezioni di questa pagina, scopri gli altri tag che possono essere applicati a un thread.

Deadlocked

Tutti i thread che risultano coinvolti in un deadlock che ha portato all'ANR vengono annotati con questo tag Deadlocked.

Un deadlock si verifica quando un thread entra in uno stato di attesa perché una risorsa richiesta è occupata da un altro thread, che attende anche una risorsa occupata dal primo thread. Se il thread principale dell'app si trova in questa situazione, è probabile che si verifichino errori ANR.

Ecco due thread coinvolti in un deadlock:

main (unknown): tid=1 systid=1568
    com.android.server.pm.PackageManagerService$PackageManagerInternalImpl.getPackage(PackageManagerService.java:22701)
    com.android.server.pm.PackageManagerService$PackageManagerInternalImpl.filterOnlySystemPackages(PackageManagerService.java:22787)

    ...

    com.android.server.SystemServer.main(SystemServer.java:368)
     java.lang.reflect.Method.invoke(Native method)
    com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:517)
    com.android.internal.os.ZygoteInit.main(ZygoteInit.java:934)


ActivityManager (unknown): tid=21 systid=1902
    com.android.server.pm.PackageManagerService.getPackageSetting(PackageManagerService.java:23618)
    com.android.server.pm.PackageManagerService.getPackageUid(PackageManagerService.java:4542)

    ...

    android.os.Handler.handleCallback(Handler.java:907)
    android.os.Handler.dispatchMessage(Handler.java:99)
    android.os.Looper.loop(Looper.java:216)
    android.os.HandlerThread.run(HandlerThread.java:67)
    com.android.server.ServiceThread.run(ServiceThread.java:44)
  

Suggerimento

Esamina i thread coinvolti nel deadlock e controlla le risorse/i blocchi acquisiti da questi thread. Per possibili soluzioni, consulta Deadlock e Algoritmi di prevenzione dei deadlock.

IO Root blocking

Qualsiasi thread che stava eseguendo operazioni di I/O lente e ha bloccato il Triggered ANR viene annotato con il IO Root blocking. Se il Triggered ANR thread non è bloccato da altri thread, il IO Root blocking thread è anche un Root blocking thread.

Thread main(THREAD_STATE_TIMED_WAITING)
   sun.misc.Unsafe.park( Unsafe.java:0 )
   java.util.concurrent.locks.LockSupport.parkNanos( LockSupport.java:230 )
   android.database.sqlite.SQLiteConnectionPool.waitForConnection( SQLiteConnectionPool.java:756 )

   ...

   android.app.ActivityThread.main( ActivityThread.java:8192 )
  
Thread main(THREAD_STATE_NATIVE_WAITING)
   Syscall
   art::ConditionVariable::WaitHoldingLocks(art::Thread*)
   art::GoToRunnable(art::Thread*)
   art::JniMethodEnd(unsigned int, art::Thread*)
   libcore.io.Linux.fdatasync( Linux.java:0 )
   libcore.io.ForwardingOs.fdatasync( ForwardingOs.java:105 )

...

   java.io.RandomAccessFile.write( RandomAccessFile.java:559 )

...

   android.app.ActivityThread.main( ActivityThread.java:8192 )
  

Suggerimento

In generale, l'app non deve eseguire operazioni di I/O costose sul thread principale. Se il thread principale è IO Root blocking, puoi anche utilizzare la modalità rigorosa per identificare eventuali operazioni di I/O indesiderate che si verificano nel thread principale.

Root blocking

Qualsiasi thread che ha bloccato il thread contrassegnato come Triggered ANR è annotato con il tag Root blocking. Se un thread è contrassegnato sia come Root blocking che come Triggered ANR, non ci sono altri thread che lo bloccano.

Se eventuali thread Triggered ANR erano in attesa (forse in modo transitivo) di altri thread, sono Root blocking. Esistono diversi motivi per cui un thread è la causa principale dell'ANR.

Ecco alcuni esempi basati sullo stato del thread:

Thread main(THREAD_STATE_RUNNABLE)
   android.os.Parcel.createTypedArray( Parcel.java:3086 )
   android.content.pm.PackageInfo.<init>( PackageInfo.java:546 )

...

   android.app.ActivityThread$H.handleMessage( ActivityThread.java:2166 )
   android.os.Handler.dispatchMessage( Handler.java:106 )
   android.os.Looper.loop( Looper.java:246 )
   android.app.ActivityThread.main( ActivityThread.java:8633 )
  
Thread main(THREAD_STATE_BLOCKED)
   DBHelper.runOnDB( DBHelper.java:97 )
   DBHelper.runDb( DBHelper.java:125 )

...

   java.lang.reflect.Method.invoke( Method.java:0 )
   EventBus.invokeSubscriber( EventBus.java:510 )
   postToSubscription( EventBus.java:437 )

...

   android.os.Handler.handleCallback( Handler.java:938 )
   android.os.Handler.dispatchMessage( Handler.java:99 )
   android.os.Looper.loop( Looper.java:268 )
   android.app.ActivityThread.main( ActivityThread.java:7904 )
  

Suggerimento

Riduci al minimo il lavoro che richiede un'elevata intensità di risorse della CPU nel thread principale. Utilizza thread di lavoro o in background per eseguire attività che richiedono un'elevata intensità di risorse della CPU.

Riduci al minimo il lavoro che richiede un'I/O elevata, come il caricamento da un database, nel thread principale.

Unknown root cause

Un thread viene contrassegnato con il tag Unknown root cause se è stato il thread che ha attivato l'ANR, ma era inattivo nel processo quando si è verificato l'ANR. Crashlytics non dispone di informazioni sufficienti per determinare la causa principale. Non è evidente il motivo per cui si è verificato questo errore ANR.

Thread main(THREAD_STATE_NATIVE_WAITING)    __epoll_pwait
    android::Looper::pollInner(int)
    android::Looper::pollOnce(int, int*, int*, void**)
    android::android_os_MessageQueue_nativePollOnce(_JNIEnv*, _jobject*, long, int)
    android.os.MessageQueue.nativePollOnce( MessageQueue.java:0 )
    android.os.MessageQueue.next( MessageQueue.java:335 )
    android.os.Looper.loop( Looper.java:193 )
    android.app.ActivityThread.main( ActivityThread.java:8019 )
  

Suggerimento

Segui i consigli generali su come evitare gli errori ANR. Ad esempio, identifica i punti del codice in cui il thread principale dell'app può essere occupato per più di 5 secondi.