Depure seu aplicativo Android com base em tags ANR no painel do Crashlytics

Erros de aplicativo que não responde (ANR) são acionados quando o thread de UI do aplicativo não responde por mais de 5 segundos . Você pode ler mais sobre ANRs e como diagnosticar ANRs na documentação do Android .

Além disso, o Crashlytics pode ajudar a identificar tópicos problemáticos específicos. Analisamos ANRs e, em seguida, no painel do Crashlytics , marcamos os threads aplicáveis ​​para fornecer dicas sobre como depurar o ANR.

As seções a seguir nesta página explicam o que cada tag ANR significa, mostram um exemplo de ANR com essa tag e fornecem uma solução recomendada para depurar o ANR.

Triggered ANR

Um thread que foi bloqueado por muito tempo e acionou o ANR é anotado com este Etiqueta Triggered ANR .

O thread problemático pode ser o thread principal do aplicativo ou qualquer thread que não esteja respondendo. No entanto, o tópico marcado como Triggered ANR pode ou não ser a causa real da ANR. Para fornecer insights para depuração e correção desses ANRs, o Crashlytics também marca quaisquer outros threads envolvidos no ANR. Nas seções seguintes desta página, aprenda sobre outras tags que podem ser aplicadas a um tópico.

Deadlocked

Quaisquer threads que estejam envolvidos em um deadlock que levou ao ANR são anotados com este Tag Deadlocked .

Um deadlock ocorre quando um thread entra em estado de espera porque um recurso necessário está retido por outro thread, que também está aguardando um recurso retido pelo primeiro thread. Se o thread principal do aplicativo estiver nessa situação, é provável que ocorram ANRs.

Aqui estão dois threads envolvidos em um impasse:

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)
 

Recomendação

Observe os threads envolvidos no deadlock e verifique os recursos/bloqueios adquiridos por esses threads. Consulte Algoritmos de prevenção de Deadlock e Deadlock para possíveis soluções.

IO Root blocking

Qualquer thread que estava executando operações de E/S lentas e bloqueou o O thread Triggered ANR é anotado com o Tag IO Root blocking . Se o O thread Triggered ANR não é bloqueado por outros threads, então o Thread IO Root blocking também é um Thread Root blocking .

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 )
 

Recomendação

Em geral, seu aplicativo não deve executar operações de E/S caras no thread principal. No caso do thread principal ser IO Root blocking , você também pode usar o modo estrito para identificar quaisquer operações de E/S não intencionais que estejam acontecendo no thread principal.

Root blocking

Qualquer tópico que bloqueou o tópico marcado como Triggered ANR é anotado com o Tag Root blocking . Se um tópico estiver marcado como ambos Root blocking e Triggered ANR , então não há outros threads que bloqueiem esse thread.

Caso existam Threads Triggered ANR estavam aguardando (talvez transitivamente) por outros threads, eles são Root blocking . Pode haver vários motivos pelos quais um thread é a causa raiz do ANR.

Aqui estão alguns exemplos baseados no estado do 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 )
 

Recomendação

Minimize o trabalho intensivo da CPU no thread principal. Use threads de trabalho ou de segundo plano para executar tarefas com uso intensivo de CPU.

Minimize o trabalho intensivo de E/S, como carregar de um banco de dados, no thread principal.

Unknown root cause

Um tópico é marcado com o Tag Unknown root cause se foi o thread que acionou o ANR, mas estava ocioso no processo quando o ANR ocorreu. O Crashlytics não possui informações suficientes para determinar a causa raiz. Não há nenhuma razão evidente para a ocorrência desta 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 )
 

Recomendação

Siga os conselhos gerais sobre como prevenir ANRs. Por exemplo, identifique os locais no seu código onde o thread principal do aplicativo pode ficar ocupado por mais de cinco segundos .