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