當應用程式的 UI 執行緒超過5 秒沒有回應時,會觸發應用程式未回應 (ANR) 錯誤。您可以在Android 文件中閱讀有關 ANR 和診斷 ANR 的更多資訊。
此外,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
任何正在執行緩慢 I/O 操作並阻塞的線程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 )
推薦
一般來說,您的應用程式不應在主執行緒上執行昂貴的 I/O 操作。在主線程的情況下IO Root blocking
,您也可以使用嚴格模式來識別主執行緒上發生的任何無意的 I/O 操作。
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 )
推薦
最大限度地減少主執行緒中的 CPU 密集型工作。使用工作執行緒或後台執行緒執行 CPU 密集型任務。
最大限度地減少主執行緒上的 I/O 密集型工作,例如從資料庫載入。
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 秒的位置。