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