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