ANR-Fehler werden ausgelöst, wenn der UI-Thread der Anwendung länger als 5 Sekunden nicht antwortet. Weitere Informationen zu ANRs und zur Diagnose von ANRs finden Sie in der Android-Dokumentation.
Außerdem kann Crashlytics dabei helfen, bestimmte problematische Threads zu ermitteln. Wir analysieren ANRs und taggen dann im 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 finden Sie ein Beispiel für einen ANR mit diesem Tag und eine empfohlene Lösung zur Fehlerbehebung.
Triggered ANR
Threads, die zu lange blockiert waren und den ANR-Fehler ausgelöst haben, werden mit diesem Triggered ANR
-Tag gekennzeichnet.
Der problematische Thread kann der Hauptthread der App oder ein beliebiger Thread sein, der nicht reagiert. Der Thread, der mit Triggered ANR
getaggt ist, ist jedoch nicht unbedingt die tatsächliche Ursache für den ANR. Um Informationen zum Beheben dieser ANRs bereitzustellen, werden mit Crashlytics auch alle anderen Threads getaggt, die am ANR beteiligt sind. In den folgenden Abschnitten 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 den Wartestatus 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 Haupt-Thread der App in dieser Situation befindet, treten wahrscheinlich ANRs auf.
Beispiel ansehen
Hier sind zwei Threads zu sehen, 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 am Deadlock beteiligt sind, und prüfen Sie die von diesen Threads erworbenen Ressourcen/Sperren. Mögliche Lösungen finden Sie unter Deadlock und Deadlock-Präventionsalgorithmen.
IO Root blocking
Alle Threads, die langsame E/A-Vorgänge ausgeführt und den Thread Triggered ANR
blockiert haben, sind mit dem Tag IO Root blocking
gekennzeichnet. Wenn der Triggered ANR
-Thread nicht von anderen Threads blockiert wird, ist er auch ein Root blocking
-Thread.IO Root blocking
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 Anwendung keine teuren E/A-Vorgänge im Hauptthread ausführen. Wenn der Hauptthread IO Root blocking
ist, können Sie auch den strengen Modus verwenden, um unbeabsichtigte E/A-Vorgänge im Hauptthread zu identifizieren.
Root blocking
Jeder Thread, der den als Triggered ANR
getaggten Thread blockiert hat, wird mit dem Tag Root blocking
gekennzeichnet. Wenn ein Thread sowohl mit Root blocking
als auch mit Triggered ANR
getaggt ist, gibt es keine weiteren Threads, die diesen Thread blockieren.
Wenn Triggered ANR
-Threads (möglicherweise vorübergehend) auf andere Threads gewartet haben, sind sie Root blocking
. Es kann verschiedene Gründe geben, warum ein Thread die Ursache für die ANR ist.
Beispiele ansehen
Hier einige Beispiele, die auf dem Thread-Status basieren:
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
CPU-intensive Arbeit im Hauptthread minimieren Verwenden Sie Worker- oder Hintergrundthreads, um CPU-intensive Aufgaben auszuführen.
Minimieren Sie E/A-intensive Arbeit, wie das Laden aus einer Datenbank im Hauptthread.
Unknown root cause
Ein Thread wird mit dem Tag Unknown root cause
getaggt, wenn er den ANR-Fehler ausgelöst hat, aber im Prozess inaktiv war, als der ANR-Fehler aufgetreten ist. In Crashlytics liegen nicht genügend Informationen vor, um die Ursache zu ermitteln. Es gibt keinen offensichtlichen Grund für diesen ANR-Fehler.
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 der allgemeinen Anleitung zum Vermeiden von ANRs. Ermitteln Sie beispielsweise die Stellen in Ihrem Code, an denen der Haupt-Thread der App länger als 5 Sekunden belegt sein kann.