ऐप्लिकेशन के बंद होने (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 )
सुझाव
एएनआर को रोकने के तरीके के बारे में सामान्य सलाह का पालन करें. उदाहरण के लिए, अपने कोड में उन
जगहों की पहचान करें जहां ऐप्लिकेशन का मुख्य थ्रेड पांच सेकंड से ज़्यादा समय तक व्यस्त हो सकता है
.