Lỗi Ứng dụng không phản hồi (ANR) được kích hoạt khi luồng giao diện người dùng của ứng dụng không phản hồi trong hơn
Ngoài ra, Crashlytics có thể giúp xác định chính xác các luồng có vấn đề. Chúng ta phân tích các lỗi ANR, sau đó, trong trang tổng quan Crashlytics, chúng ta gắn thẻ các luồng có thể áp dụng để đưa ra gợi ý về cách gỡ lỗi ANR.
Các phần sau trên trang này giải thích ý nghĩa của từng thẻ ANR, cho thấy một lỗi ANR mẫu có thẻ đó và đưa ra giải pháp đề xuất để gỡ lỗi ANR.
Triggered ANR
Một luồng đã bị chặn quá lâu và kích hoạt ANR sẽ được chú thích bằng thẻ Triggered ANR
Luồng có vấn đề có thể là luồng chính của ứng dụng, hoặc bất kỳ luồng nào được phát hiện là không phản hồi. Tuy nhiên, luồng được gắn thẻ là Triggered ANR
Deadlocked
Mọi luồng được phát hiện có liên quan đến tình trạng tắc nghẽn dẫn đến ANR đều được chú thích bằng thẻ Deadlocked
Tình trạng tắc nghẽn sẽ xảy ra khi một luồng chuyển sang trạng thái chờ vì một tài nguyên cần thiết được giữ lại trong một luồng khác, đồng thời đang chờ tài nguyên do luồng đầu tiên lưu giữ. Nếu luồng chính của ứng dụng rơi vào trường hợp này, thì nhiều khả năng lỗi ANR sẽ xảy ra.
Xem ví dụ
Dưới đây là hai luồng liên quan đến tình trạng tắc nghẽn:
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)
Đề xuất
Xem các luồng liên quan đến tình trạng tắc nghẽn và kiểm tra tài nguyên/khoá mà các luồng đó đã thu nạp. Hãy tham khảo bài viết về Tắc nghẽn và Thuật toán ngăn chặn tắc nghẽn để biết các giải pháp khả thi.
IO Root blocking
Bất kỳ luồng nào đang thực thi các thao tác nhập/xuất (I/O) chậm và đã chặn luồng Triggered ANR
IO Root blocking
Triggered ANR
IO Root blocking
Root blocking
Xem ví dụ
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 )
Đề xuất
Nhìn chung, ứng dụng của bạn không nên thực thi các thao tác I/O tốn kém trên luồng chính. Trong trường hợp luồng chính là IO Root blocking
Root blocking
Bất kỳ luồng nào đã chặn luồng được gắn thẻ là Triggered ANR
Root blocking
Root blocking
Triggered ANR
Nếu bất kỳ luồng Triggered ANR
Root blocking
Xem ví dụ
Sau đây là một số ví dụ dựa trên trạng thái luồng:
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 )
Đề xuất
Giảm thiểu công việc nặng về CPU trong luồng chính. Sử dụng luồng worker hoặc luồng trong nền để thực hiện các tác vụ nặng về CPU.
Giảm thiểu công việc chuyên sâu về I/O, chẳng hạn như tải từ cơ sở dữ liệu, trên luồng chính.
Unknown root cause
Một luồng được gắn thẻ bằng thẻ Unknown root cause
Xem ví dụ
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 )
Đề xuất
Làm theo lời khuyên chung về cách ngăn chặn lỗi ANR. Ví dụ: xác định các vị trí trong mã của bạn nơi luồng chính của ứng dụng có thể bận trong hơn