当应用的界面线程在
此外,Crashlytics 还有助于查明有问题的具体线程。我们会分析 ANR,然后在 Crashlytics 信息中心中标记相应的线程,以便提供有关如何调试 ANR 的提示。
本页面的以下部分介绍了每个 ANR 标记的含义,展示了带有该标记的示例 ANR,并提供了调试 ANR 的建议解决方案。
Triggered ANR
被阻止的时间过长并触发 ANR 的线程会被添加此 Triggered ANR
存在问题的线程可以是应用的主线程,也可以是被发现无响应的任何线程。不过,标记为 Triggered 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
Root blocking
阻止标记为 Triggered ANR
Root blocking
Root blocking
Triggered ANR
如果任何 Triggered ANR
Root blocking
查看示例
以下是基于线程状态的一些示例:
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
如果某个线程触发了 ANR,但在 ANR 发生时处于空闲状态,则系统会使用 Unknown root cause
查看示例
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 的一般建议。例如,在您的代码中找出应用的主线程处于忙碌状态的时间可能超过