Uygulama yanıt vermiyor (ANR) hataları, uygulamanın kullanıcı arayüzü iş parçacığı 5 saniyeden uzun süre yanıt vermediğinde tetiklenir. ANR'ler ve ANR'lerin teşhis edilmesi hakkında daha fazla bilgiyi Android belgelerinde bulabilirsiniz.
Ayrıca, Crashlytics belirli sorunlu ileti dizilerini belirlemeye yardımcı olabilir. ANR'leri analiz ederiz ve ardından DevOps & Engagement > Crashlytics kontrol panelinde, ANR'de nasıl hata ayıklanacağıyla ilgili ipuçları vermek için geçerli iş parçacıklarını etiketleriz.
Bu sayfadaki aşağıdaki bölümlerde, her bir ANR etiketinin ne anlama geldiği açıklanmakta, bu etikete sahip bir ANR örneği gösterilmekte ve ANR'de hata ayıklamak için önerilen bir çözüm sunulmaktadır.
Triggered ANR
Çok uzun süre engellenen ve ANR'yi tetikleyen iş parçacığına bu Triggered ANR etiketi eklenir.
Sorunlu iş parçacığı, uygulamanın ana iş parçacığı veya yanıt vermediği tespit edilen herhangi bir iş parçacığı olabilir. Ancak Triggered ANR olarak etiketlenen iş parçacığı, ANR'nin gerçek nedeni olabilir veya olmayabilir. Bu ANR'lerin hata ayıklanması ve düzeltilmesi için analizler sağlamak üzere Crashlytics, ANR'ye dahil olan diğer tüm iş parçacıklarını da etiketler. Bu sayfanın aşağıdaki bölümlerinde, bir ileti dizisine uygulanabilecek diğer etiketler hakkında bilgi edinin.
Deadlocked
ANR'ye yol açan bir kilitlenmeye karıştığı tespit edilen tüm iş parçacıkları bu Deadlocked etiketiyle açıklama eklenir.
Bir iş parçacığı, gerekli bir kaynak başka bir iş parçacığı tarafından tutulduğu için bekleme durumuna girdiğinde kilitlenme oluşur. Bu iş parçacığı da ilk iş parçacığı tarafından tutulan bir kaynağı beklemektedir. Uygulamanın ana iş parçacığı bu durumdaysa ANR'lerin oluşması muhtemeldir.
Örneği göster
Kilitlenmeye neden olan iki iş parçacığı aşağıda verilmiştir:
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)
Öneri
Kilitlenmeye dahil olan iş parçacıklarına bakın ve bu iş parçacıkları tarafından edinilen kaynakları/kilitleri kontrol edin. Olası çözümler için Kilitlenme ve Kilitlenmeyi önleme algoritmaları başlıklı makalelere bakın.
IO Root blocking
Yavaş G/Ç işlemleri yürüten ve Triggered ANR iş parçacığını engelleyen tüm iş parçacıkları IO Root blocking etiketiyle açıklama eklenir. Triggered ANR iş parçacığı diğer iş parçacıkları tarafından engellenmiyorsa IO Root blocking iş parçacığı da Root blocking iş parçacığıdır.
Örnekleri göster
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 )
Öneri
Genel olarak, uygulamanız ana iş parçacığında maliyetli G/Ç işlemleri yürütmemelidir. Ana iş parçacığı IO Root blocking olduğunda, ana iş parçacığında gerçekleşen istenmeyen G/Ç işlemlerini belirlemek için katı modu da kullanabilirsiniz.
Root blocking
Triggered ANR olarak etiketlenen ileti dizisini engelleyen tüm ileti dizileri Root blocking etiketiyle açıklama eklenir. Bir ileti dizisi hem Root blocking hem de Triggered ANR olarak etiketlenirse bu ileti dizisini engelleyen başka ileti dizisi yoktur.
Diğer iş parçacıklarının tamamlanmasını bekleyen (belki de geçişli olarak) Triggered ANR iş parçacıkları varsa bunlar Root blocking. Bir iş parçacığının ANR'nin temel nedeni olmasının çeşitli nedenleri olabilir.
Örnekleri göster
İş parçacığı durumuna göre birkaç örnek:
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 )
Öneri
Ana iş parçacığında CPU yoğun işi en aza indirin. CPU yoğun görevleri gerçekleştirmek için çalışan veya arka plan iş parçacıklarını kullanın.
Ana iş parçacığında veritabanından yükleme gibi G/Ç yoğun işleri en aza indirin.
Unknown root cause
Bir ileti dizisi, ANR'yi tetikleyen ileti dizisi olmasına rağmen ANR oluştuğu sırada işlemde boşta ise Unknown root cause etiketiyle etiketlenir. Crashlytics, temel nedeni belirlemek için yeterli bilgiye sahip değil. Bu ANR'nin neden oluştuğuna dair belirgin bir neden yok.
Örneği göster
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 )
Öneri
ANR'leri önleme ile ilgili genel tavsiyelere uyun. Örneğin, kodunuzda uygulamanın ana iş parçacığının 5 saniyeden uzun süre meşgul olabileceği yerleri belirleyin.
Waiting for binder call
Bir bağlayıcı çağrısı bekleyen ve Triggered ANR iş parçacığını engelleyen tüm iş parçacıkları Waiting for binder call etiketiyle açıklama eklenir. Triggered ANR iş parçacığı diğer iş parçacıkları tarafından engellenmiyorsa Waiting for binder call iş parçacığı da Root blocking iş parçacığıdır.
Örneği göster
Thread main(THREAD_STATE_NATIVE_WAITING)
syscall
android::IPCThreadState::talkWithDriver(bool)
android::IPCThreadState::waitForResponse(android::Parcel*, int*)
android::IPCThreadState::transact(int, unsigned int, android::Parcel const&, android::Parcel*, unsigned int)
android::BpBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)
android_os_BinderProxy_transact(_JNIEnv*, _jobject*, int, _jobject*, _jobject*, int)
android.os.BinderProxy.transactNative( BinderProxy.java:0 )
android.os.BinderProxy.transact( BinderProxy.java:540 )
android.app.IActivityManager$Stub$Proxy.getContentProvider( IActivityManager.java:5945 )
android.app.ActivityThread.acquireProvider( ActivityThread.java:7138 )
android.app.ActivityThread$H.handleMessage( ActivityThread.java:1982 )
android.os.Handler.dispatchMessage( Handler.java:106 )
android.os.Looper.loop( Looper.java:236 )
android.app.ActivityThread.main( ActivityThread.java:8037 )
Öneri
Bağlayıcı çağrısının gecikmesi tahmin edilemez olabileceğinden, bağlayıcı çağrılarını G/Ç işlemleri gibi değerlendirin ve mümkün olduğunda ana iş parçacığında yapmaktan kaçının. Bağlayıcı çağrılarını tetikleyen kodu (bağlayıcı işlemleriyle sonuçlanan platform API çağrıları dahil) arka plan ileti dizisine taşıyın veya ana ileti dizisinden çağırmak kaçınılmazsa sonuçları önbelleğe alın.