ऐप्लिकेशन में कोई समस्या है (ANR) से जुड़ी गड़बड़ियां तब ट्रिगर होती हैं, जब ऐप्लिकेशन का यूज़र इंटरफ़ेस (यूआई) थ्रेड 5 सेकंड से ज़्यादा समय तक काम नहीं करता है. Android दस्तावेज़ में, एएनआर और एएनआर का पता लगाने के बारे में ज़्यादा पढ़ा जा सकता है.
इसके अलावा, Crashlytics की मदद से, समस्या वाली खास थ्रेड की पहचान की जा सकती है. हम ANR का विश्लेषण करते हैं. इसके बाद, Crashlytics डैशबोर्ड में, हम लागू होने वाली थ्रेड को टैग करते हैं, ताकि ANR को डीबग करने का तरीका बताया जा सके.
इस पेज के इन सेक्शन में बताया गया है कि हर एएनआर टैग का क्या मतलब होता है. यह उस टैग में हुए एएनआर का उदाहरण दिखाता है और एएनआर को डीबग करने के लिए सुझाया गया तरीका भी बताता है.
Triggered ANR
जिस थ्रेड को बहुत लंबे समय तक ब्लॉक किया गया था और जिसकी वजह से ANR ट्रिगर हुआ था उसे इस Triggered ANR
टैग के साथ एनोटेट किया गया है.
समस्या वाली थ्रेड, ऐप्लिकेशन की मुख्य थ्रेड हो सकती है या ऐसी कोई भी थ्रेड हो सकती है जो काम नहीं कर रही है. हालांकि, Triggered ANR
के तौर पर टैग की गई थ्रेड, एएनआर की असल वजह हो सकती है या नहीं भी. ANR वाली गड़बड़ियों को डीबग और ठीक करने के बारे में अहम जानकारी देने के लिए,
Crashlytics, ANR वाली गड़बड़ी की वजह से शामिल अन्य थ्रेड को भी टैग करता है. इस पेज के नीचे दिए गए सेक्शन में, उन दूसरे टैग के बारे में जानें जिन्हें थ्रेड पर लागू किया जा सकता है.
Deadlocked
जिन थ्रेड में डेडलॉक की वजह से एएनआर हुआ है उन्हें इस 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 )
सुझाव
मुख्य थ्रेड में सीपीयू पर कम समय तक काम करें. सीपीयू पर ज़्यादा लोड डालने वाले टास्क करने के लिए, वर्कर्स या बैकग्राउंड थ्रेड का इस्तेमाल करें.
मुख्य थ्रेड पर, डेटाबेस से लोड करने जैसे ज़्यादा 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 )
सुझाव
एएनआर से बचने के तरीके के बारे में सामान्य सलाह अपनाएं. उदाहरण के लिए, अपने कोड में उन जगहों की पहचान करें जहां ऐप्लिकेशन का मुख्य थ्रेड पांच सेकंड से ज़्यादा समय तक व्यस्त हो सकता है.