Błędy typu Aplikacja nie odpowiada (ANR) są wywoływane, gdy wątek interfejsu aplikacji nie odpowiada przez ponad
Crashlytics może też pomóc w określaniu konkretnych wątków, które mogą być problemowe. Analizujemy błędy ANR, a potem na panelu Crashlytics otagowujemy odpowiednie wątki, aby wyświetlać wskazówki dotyczące ich debugowania.
W następnych sekcjach tej strony wyjaśniamy, co oznaczają poszczególne tagi błędów ANR, przedstawiamy przykładowy błąd ANR z takim tagiem oraz podajemy zalecane rozwiązanie umożliwiające debugowanie tego błędu.
Triggered ANR
Wątek, który był zablokowany zbyt długo i wywołał błąd ANR, jest oznaczony tagiem Triggered ANR
Problem może dotyczyć głównego wątku aplikacji lub dowolnego wątku, który nie odpowiada. Wątek otagowany jako Triggered ANR
Deadlocked
Wszystkie wątki, które okazały się zaangażowane w blokadę wzajemną, która wywołała błąd ANR, są oznaczone tym tagiem Deadlocked
Blokada występuje, gdy wątek przechodzi w stan oczekiwania, ponieważ wymagany zasób jest zablokowany przez inny wątek, który również oczekuje na zasób zablokowany przez pierwszy wątek. Jeśli główny wątek aplikacji znajduje się w takiej sytuacji, prawdopodobnie będą się pojawiać błędy ANR.
Zobacz przykład
Oto 2 wątki, które uczestniczą w zakleszczeniu:
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)
Rekomendacja
Sprawdź wątki zaangażowane w błąd Deadlock i sprawdź zasoby/blokady uzyskane przez te wątki. Możliwe rozwiązania znajdziesz w artykule Deadlock (w języku angielskim) i Algorytmy zapobiegające blokowaniu się (w języku angielskim).
IO Root blocking
Każdy wątek, który wykonywał powolne operacje wejścia-wyjścia i zablokował wątek Triggered ANR
IO Root blocking
Triggered ANR
IO Root blocking
Root blocking
Zobacz przykłady
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 )
Rekomendacja
Ogólnie rzecz biorąc, aplikacja nie powinna wykonywać kosztownych operacji wejścia-wyjścia w wątku głównym. Jeśli wątek główny jestIO Root blocking
Root blocking
Każdy wątek, który zablokował wątek otagowany jako
Triggered ANR
Root blocking
Root blocking
Triggered ANR
Jeśli jakieś wątki Triggered ANR
Root blocking
Zobacz przykłady
Oto kilka przykładów dotyczących stanu wątku:
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 )
Rekomendacja
Zminimalizuj obciążenie procesora w wątku głównym. Do wykonywania zadań wymagających dużej mocy obliczeniowej procesora używaj wątków roboczych lub wątków działających w tle.
Zminimalizuj intensywne operacje we/wy, takie jak wczytywanie z bazy danych, w wątku głównym.
Unknown root cause
Wątek jest oznaczony tagiem Unknown root cause
Zobacz przykład
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 )
Rekomendacja
Postępuj zgodnie z ogólnymi wskazówkami dotyczącymi zapobiegania błędom ANR. Na przykład zidentyfikuj miejsca w kodzie, w których wątek główny aplikacji może być zajęty dłużej niż