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