„App antwortet nicht“-Fehler (ANR) werden ausgelöst, wenn der UI-Thread der
Anwendung länger als 5 Sekunden nicht reagiert. Weitere Informationen zu ANR-Fehlern und ihrer Diagnose finden Sie in der
Android-Dokumentation.
Außerdem kann Crashlytics helfen, bestimmte problematische Threads zu identifizieren. Wir
analysieren ANR-Fehler und kennzeichnen dann im
DevOps & Engagement > Crashlytics Dashboard die
entsprechenden Threads, um Hinweise zur Fehlerbehebung zu geben.
In den folgenden Abschnitten auf dieser Seite wird erläutert, was die einzelnen ANR-Tags bedeuten. Außerdem wird ein Beispiel für einen ANR-Fehler mit diesem Tag gezeigt und eine empfohlene Lösung zur Fehlerbehebung angegeben.
Triggered ANR
Ein Thread, der zu lange blockiert wurde und den ANR-Fehler ausgelöst hat, wird mit
diesem Triggered ANR Tag gekennzeichnet.
Der problematische Thread kann der Hauptthread der App oder ein beliebiger Thread sein, der nicht reagiert. Der mit
Triggered ANR gekennzeichnete Thread ist jedoch möglicherweise nicht die tatsächliche Ursache von
dem ANR-Fehler. Um Einblicke für die Fehlerbehebung und Behebung dieser ANR-Fehler zu geben,
Crashlytics kennzeichnet auch alle anderen Threads, die an dem ANR-Fehler beteiligt sind. In den folgenden Abschnitten auf dieser Seite erfahren Sie mehr über die anderen Tags, die auf einen Thread angewendet werden können.
Deadlocked
Alle Threads, die an einem Deadlock beteiligt sind, der zum ANR-Fehler geführt hat, werden
mit diesem Deadlocked-Tag gekennzeichnet.
Ein Deadlock tritt auf, wenn ein Thread in einen Wartezustand wechselt, weil eine erforderliche Ressource von einem anderen Thread gehalten wird, der ebenfalls auf eine Ressource wartet, die vom ersten Thread gehalten wird. Wenn sich der Hauptthread der App in dieser Situation befindet, treten wahrscheinlich ANR-Fehler auf.
Beispiel ansehen
Hier sind zwei Threads, die an einem Deadlock beteiligt sind:
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)
Empfehlung
Sehen Sie sich die Threads an, die an dem Deadlock beteiligt sind, und prüfen Sie die Ressourcen/Sperren, die von diesen Threads erworben wurden. Mögliche Lösungen finden Sie unter
Deadlock und
Deadlock-Vermeidungsalgorithmen.
IO Root blocking
Alle Threads, die langsame E/A-Vorgänge ausgeführt und den
Triggered ANR Thread blockiert haben, werden mit dem
IO Root blocking Tag gekennzeichnet. Wenn der
Triggered ANR-Thread nicht durch andere Threads blockiert wird,
dann ist der IO Root blocking-Thread auch ein
Root blocking-Thread.
Beispiele ansehen
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 )
Empfehlung
Im Allgemeinen sollte Ihre App keine aufwendigen E/A-Vorgänge im Hauptthread ausführen. Wenn der Hauptthread
IO Root blocking ist, können Sie auch
den Strict Mode
verwenden, um unbeabsichtigte E/A-Vorgänge zu identifizieren, die im Haupt
thread ausgeführt werden.
Root blocking
Alle Threads, die den Thread mit dem Tag
Triggered ANR blockiert haben, werden mit dem Tag
Root blocking gekennzeichnet. Wenn ein Thread sowohl mit
Root blocking als auch mit
Triggered ANR gekennzeichnet ist, gibt es keine anderen Threads, die diesen Thread
blockieren.
Wenn Triggered ANR-Threads auf andere Threads gewartet haben (möglicherweise
transitiv), sind sie
Root blocking. Es kann verschiedene Gründe geben, warum ein Thread eine Ursache für den ANR-Fehler ist.
Beispiele ansehen
Hier sind einige Beispiele basierend auf dem Threadstatus:
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 )
Empfehlung
Minimieren Sie CPU-intensive Aufgaben im Hauptthread. Verwenden Sie Worker- oder Hintergrundthreads für CPU-intensive Aufgaben.
Minimieren Sie E/A-intensive Aufgaben wie das Laden aus einer Datenbank im Hauptthread.
Unknown root cause
Ein Thread wird mit dem Unknown root cause Tag gekennzeichnet, wenn
er den ANR-Fehler ausgelöst hat, aber im Prozess inaktiv war, als der
ANR-Fehler aufgetreten ist. Crashlytics hat nicht genügend Informationen, um
die Ursache zu ermitteln. Es gibt keinen offensichtlichen Grund, warum dieser ANR-Fehler aufgetreten ist.
Beispiel ansehen
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 )
Empfehlung
Folgen Sie den allgemeinen Empfehlungen zur Vermeidung von ANR-Fehlern. Identifizieren Sie beispielsweise die
Stellen in Ihrem Code, an denen der Hauptthread der App länger als
5 Sekundenbeschäftigt sein kann.