Gli errori relativi ad applicazioni che non rispondono (ANR) vengono attivati quando il thread dell'interfaccia utente dell'
applicazione non risponde per più di 5 secondi. Puoi leggere
ulteriori informazioni sugli ANR e sulla loro diagnosi nella
documentazione di Android.
Inoltre, Crashlytics può aiutarti a individuare thread problematici specifici. Analizziamo gli ANR e poi, nella
dashboardCrashlytics, contrassegniamo i thread applicabili per fornire suggerimenti su come eseguire il debug dell'ANR.
Le sezioni seguenti di questa pagina spiegano il significato di ogni 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 bloccato per troppo tempo e che ha attivato l'ANR è annotato con
questo Triggered ANR tag.
Il thread problematico può essere il thread principale dell'app o qualsiasi thread non reattivo. Tuttavia, il thread contrassegnato come
Triggered ANR potrebbe essere o meno la causa effettiva di
ANR. Per fornire informazioni utili per il debug e la correzione di questi ANR,
Crashlytics contrassegna anche tutti gli altri thread coinvolti nell'ANR. Nelle sezioni seguenti di questa pagina, scopri gli altri tag che potrebbero essere applicati a un thread.
Deadlocked
Tutti i thread coinvolti in un deadlock che ha portato all'ANR sono
annotati con questo Deadlocked tag.
Si verifica un deadlock quando un thread entra in uno stato di attesa perché una risorsa richiesta è detenuta da un altro thread, che a sua volta è in attesa di una risorsa detenuta dal primo thread. Se il thread principale dell'app si trova in questa situazione, è probabile che si verifichino ANR.
Visualizza esempio
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 gli algoritmi di prevenzione di
deadlock e
deadlock.
IO Root blocking
Qualsiasi thread che ha eseguito operazioni di I/O lente e ha bloccato il
Triggered ANR thread è annotato con il
IO Root blocking tag. Se il
Triggered ANR thread non è bloccato da altri thread,
allora il IO Root blocking thread è anche un
Root blocking thread.
Visualizza esempi
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. Nel caso in cui il thread principale sia
IO Root blocking, puoi anche utilizzare
la modalità Strict
per identificare eventuali operazioni di I/O non intenzionali che si verificano sul thread principale.
Root blocking
Qualsiasi thread che ha bloccato il thread contrassegnato come
Triggered ANR è annotato con il
Root blocking tag. Se un thread è contrassegnato sia come
Root blocking che come
Triggered ANR, non ci sono altri thread che
lo bloccano.
Se alcuni Triggered ANR thread erano in attesa (magari
transitivamente) di altri thread, sono
Root blocking. Esistono vari motivi per cui un thread è la causa principale dell'ANR.
Visualizza esempi
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 uso intensivo della CPU nel thread principale. Utilizza thread di lavoro o in background per eseguire attività che richiedono un uso intensivo della CPU.
Riduci al minimo il lavoro che richiede un uso intensivo di I/O, ad esempio il caricamento da un database, sul 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 esiste un motivo evidente per cui si è verificato questo ANR.
Visualizza esempio
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 prevenire gli ANR. Ad esempio, identifica i
punti del codice in cui il thread principale dell'app può essere occupato per più di
5 secondi.