Отладка приложения Android на основе тегов ANR на панели инструментов Crashlytics.

Ошибки «Приложение не отвечает» (ANR) возникают, когда поток пользовательского интерфейса приложения не отвечает более 5 секунд . Подробнее об ANR и диагностике ANR можно прочитать в документации Android .

Кроме того, Crashlytics может помочь выявить конкретные проблемные темы. Мы анализируем ошибки ANR, а затем на панели управления Crashlytics помечаем соответствующие темы, чтобы предоставить подсказки о том, как отладить ошибку ANR.

В следующих разделах на этой странице объясняется, что означает каждый тег ANR, показан пример ANR с этим тегом и представлено рекомендуемое решение для отладки ANR.

Triggered ANR

Поток, который был заблокирован слишком долго и вызвал ошибку ANR, помечается этой пометкой. Triggered ANR .

Проблемным потоком может быть основной поток приложения или любой поток, который не отвечает. Однако тема с тегом Triggered ANR может быть фактической причиной ANR, а может и не быть. Чтобы предоставить информацию об отладке и исправлении этих ошибок ANR, Crashlytics также помечает любые другие потоки, участвующие в ошибке ANR. В следующих разделах этой страницы вы узнаете о других тегах, которые можно применить к цепочке.

Deadlocked

Любые потоки, оказавшиеся вовлеченными в взаимоблокировку, приведшую к ошибке ANR, помечаются этой меткой. Deadlocked тег.

Взаимная блокировка возникает, когда поток переходит в состояние ожидания, поскольку требуемый ресурс удерживается другим потоком, который также ожидает ресурса, удерживаемого первым потоком. Если основной поток приложения находится в такой ситуации, скорее всего, возникнут ошибки ANR.

Вот два потока, участвующих в тупике:

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)
  

Рекомендация

Посмотрите потоки, вовлеченные в тупик, и проверьте ресурсы/блокировки, полученные этими потоками. Возможные решения см. в разделе «Алгоритмы предотвращения взаимоблокировок и взаимоблокировок».

IO Root blocking

Любой поток, который выполнял медленные операции ввода-вывода и блокировал Triggered ANR помечается значком Тег IO Root blocking . Если Triggered ANR не блокируется другими потоками, тогда Поток IO Root blocking также является 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 )
  

Рекомендация

В общем, ваше приложение не должно выполнять дорогостоящие операции ввода-вывода в основном потоке. В случае, если основной поток IO Root blocking , вы также можете использовать строгий режим для выявления любых непреднамеренных операций ввода-вывода, происходящих в основном потоке.

Root blocking

Любой тред, заблокировавший тред, помеченный как Triggered ANR помечается значком Тег Root blocking . Если тема помечена как Root blocking и Triggered ANR , тогда нет других потоков, блокирующих этот поток.

Если таковые имеются Triggered ANR ожидали (возможно, транзитивно) других потоков. Root blocking . Могут быть различные причины, по которым поток является основной причиной ошибки ANR.

Вот несколько примеров, основанных на состоянии потока:

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 )
  

Рекомендация

Минимизируйте интенсивную работу процессора в основном потоке. Используйте рабочие или фоновые потоки для выполнения задач, интенсивно использующих процессор.

Сведите к минимуму интенсивную работу ввода-вывода, например загрузку из базы данных, в основном потоке.

Unknown root cause

Тема помечается тегом Unknown root cause если это был поток, вызвавший ошибку ANR, но бездействовавший в процессе, когда возникла ошибка ANR. Crashlytics не располагает достаточной информацией для определения основной причины. Нет очевидной причины, по которой произошел этот 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 )
  

Рекомендация

Следуйте общим советам о том, как предотвратить ошибки ANR. Например, определите места в коде, где основной поток приложения может быть занят более 5 секунд .

,

Ошибки «Приложение не отвечает» (ANR) возникают, когда поток пользовательского интерфейса приложения не отвечает более 5 секунд . Подробнее об ANR и диагностике ANR можно прочитать в документации Android .

Кроме того, Crashlytics может помочь выявить конкретные проблемные потоки. Мы анализируем ошибки ANR, а затем на панели управления Crashlytics помечаем соответствующие темы, чтобы предоставить подсказки о том, как отладить ошибку ANR.

В следующих разделах на этой странице объясняется, что означает каждый тег ANR, показан пример ANR с этим тегом и представлено рекомендуемое решение для отладки ANR.

Triggered ANR

Поток, который был заблокирован слишком долго и вызвал ошибку ANR, помечается этой пометкой. Triggered ANR .

Проблемным потоком может быть основной поток приложения или любой поток, который не отвечает. Однако тема с тегом Triggered ANR может быть фактической причиной ANR, а может и не быть. Чтобы предоставить информацию об отладке и исправлении этих ошибок ANR, Crashlytics также помечает все другие потоки, участвующие в ошибке ANR. В следующих разделах этой страницы вы узнаете о других тегах, которые можно применить к теме.

Deadlocked

Любые потоки, оказавшиеся вовлеченными в взаимоблокировку, приведшую к ошибке ANR, помечаются этой меткой. Deadlocked тег.

Взаимная блокировка возникает, когда поток переходит в состояние ожидания, поскольку требуемый ресурс удерживается другим потоком, который также ожидает ресурса, удерживаемого первым потоком. Если основной поток приложения находится в такой ситуации, скорее всего, возникнут ошибки ANR.

Вот два потока, участвующих в тупике:

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)
  

Рекомендация

Посмотрите потоки, вовлеченные в тупик, и проверьте ресурсы/блокировки, полученные этими потоками. Возможные решения см. в разделе «Алгоритмы предотвращения взаимоблокировок и взаимоблокировок».

IO Root blocking

Любой поток, который выполнял медленные операции ввода-вывода и блокировал Triggered ANR помечается значком Тег IO Root blocking . Если Triggered ANR не блокируется другими потоками, тогда Поток IO Root blocking также является 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 )
  

Рекомендация

В общем, ваше приложение не должно выполнять дорогостоящие операции ввода-вывода в основном потоке. В случае, если основной поток IO Root blocking , вы также можете использовать строгий режим для выявления любых непреднамеренных операций ввода-вывода, происходящих в основном потоке.

Root blocking

Любой тред, заблокировавший тред, помеченный как Triggered ANR помечается значком Тег Root blocking . Если тема помечена как Root blocking и Triggered ANR , тогда нет других потоков, блокирующих этот поток.

Если таковые имеются Triggered ANR ожидали (возможно, транзитивно) других потоков. Root blocking . Могут быть различные причины, по которым поток является основной причиной ошибки ANR.

Вот несколько примеров, основанных на состоянии потока:

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 )
  

Рекомендация

Минимизируйте интенсивную работу процессора в основном потоке. Используйте рабочие или фоновые потоки для выполнения задач, интенсивно использующих процессор.

Сведите к минимуму интенсивную работу ввода-вывода, например загрузку из базы данных, в основном потоке.

Unknown root cause

Тема помечается тегом Unknown root cause если это был поток, вызвавший ошибку ANR, но бездействовавший в процессе, когда возникла ошибка ANR. Crashlytics не располагает достаточной информацией для определения основной причины. Нет очевидной причины, по которой произошел этот 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 )
  

Рекомендация

Следуйте общим советам о том, как предотвратить ошибки ANR. Например, определите места в коде, где основной поток приложения может быть занят более 5 секунд .