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