ข้อผิดพลาด "แอปพลิเคชันไม่ตอบสนอง" (ANR) จะแสดงขึ้นเมื่อเธรด UI ของแอปพลิเคชันไม่ตอบสนองนานกว่า
นอกจากนี้ Crashlytics ยังช่วยระบุชุดข้อความที่มีปัญหาได้ เราจะวิเคราะห์ ANR จากนั้นในหน้าแดชบอร์ด Crashlytics เราจะติดแท็กชุดข้อความที่เกี่ยวข้องเพื่อให้คำแนะนำเกี่ยวกับวิธีแก้ไขข้อบกพร่อง ANR
ส่วนต่อไปนี้ในหน้านี้จะอธิบายความหมายของแท็ก ANR แต่ละรายการ แสดงตัวอย่าง ANR ที่มีแท็กนั้น และแสดงวิธีแก้ปัญหาที่แนะนําในการแก้ไขข้อบกพร่อง ANR
Triggered ANR
เทรดที่ถูกบล็อกนานเกินไปและเรียกให้เกิด ANR จะมีคำอธิบายประกอบด้วยแท็ก Triggered ANR
ชุดข้อความที่เป็นปัญหาอาจเป็นชุดข้อความหลักของแอป หรือชุดข้อความใดก็ตามที่พบว่าไม่ตอบสนอง อย่างไรก็ตาม เทรดที่ติดแท็กเป็น Triggered ANR
Deadlocked
เทรดใดก็ตามที่พบว่าเกี่ยวข้องกับการติดตายที่ทำให้เกิด ANR จะมีคำอธิบายประกอบด้วยแท็ก Deadlocked
การล็อกคิวเกิดขึ้นเมื่อเธรดเข้าสู่สถานะรอเนื่องจากเธรดอื่นถือครองทรัพยากรที่จําเป็นอยู่ ซึ่งก็รอทรัพยากรที่เธรดแรกถือครองอยู่ด้วย หากเทรดหลักของแอปอยู่ในสถานการณ์เช่นนี้ ก็มีโอกาสที่จะเกิด ANR
ดูตัวอย่าง
เทรด 2 รายการที่เกี่ยวข้องกับการติดตายมีดังนี้
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)
คำแนะนำ
ดูที่ชุดข้อความที่เกี่ยวข้องกับการล็อกตายและตรวจสอบทรัพยากร/ล็อกที่ชุดข้อความเหล่านั้นได้รับ โปรดดูวิธีแก้ปัญหาที่เป็นไปได้จากหัวข้อDeadlock และDeadlock prevention algorithms
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
เทรดจะติดแท็ก 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 เช่น ระบุตำแหน่งในโค้ดที่ชุดข้อความหลักของแอปอาจทำงานนานกว่า