ANR (Application Not Responding) एक Android सिस्टम सूचना है जो तब प्रकट होती है जब ऐप 5 सेकंड से अधिक समय तक उपयोगकर्ता इनपुट पर प्रतिक्रिया देना बंद कर देता है। Android Developers के अनुसार, मुख्य कारण मुख्य थ्रेड पर लंबी प्रक्रियाएँ हैं जो टच प्रोसेसिंग और UI रेंडरिंग को अवरुद्ध करती हैं। प्रतिक्रियाशील ऐप बनाने के लिए प्रत्येक Android डेवलपर के लिए ANR तंत्र को समझना आवश्यक है।
मुख्य बिंदु
ANR (Application Not Responding) Android ऑपरेटिंग सिस्टम का एक डायलॉग बॉक्स है जो तब प्रकट होता है जब ऐप उपयोगकर्ता इनपुट पर प्रतिक्रिया देना बंद कर देता है। सिस्टम InputDispatcher के माध्यम से ईवेंट प्रोसेसिंग समय को ट्रैक करता है: यदि कोई स्पर्श या बटन दबाव 5 सेकंड के भीतर संसाधित नहीं होता है, तो Android ऐप को बंद करने या प्रतीक्षा करने का विकल्प देते हुए एक डायलॉग दिखाता है।
ANR तंत्र फ्रीज़ हुए ऐप्स से उपयोगकर्ता अनुभव की रक्षा करता है। Android एक ऐप को पूरे सिस्टम को ब्लॉक करने की अनुमति नहीं देता है — डेस्कटॉप OS के विपरीत, मोबाइल प्लेटफ़ॉर्म जबरन ईवेंट प्रोसेसिंग समय को सीमित करता है। BroadcastReceiver की 10 सेकंड की सीमा है, और foreground सेवा की 20 सेकंड की सीमा है।
ANR कोड में कोई अपवाद नहीं है — यह Linux प्रक्रिया स्तर पर एक सिस्टम तंत्र है। Android प्रक्रिया को SIGQUIT सिग्नल भेजता है, जिसके बाद सिस्टम सभी थ्रेड्स के कॉल स्टैक को traces.txt फ़ाइल में सहेजता है। डेवलपर को ANR catch अपवाद के रूप में नहीं, बल्कि ऐप पुनरारंभ होने के बाद एक रिपोर्ट के रूप में प्राप्त होता है। Android 11+ पर, ApplicationExitInfo API प्रोग्रामेटिक रूप से प्रक्रिया समाप्ति का कारण प्राप्त करने की अनुमति देता है, जिसमें ANR भी शामिल है — यह मैन्युअल traces.txt पार्सिंग के बिना सांख्यिकी संग्रह को सरल बनाता है।
पाँच श्रेणियाँ की प्रक्रियाएँ Android ऐप में लगातार ANR का कारण बनती हैं। उनमें से प्रत्येक मुख्य थ्रेड को अवरुद्ध करती है, सिस्टम को इनपुट ईवेंट और स्क्रीन पुनः चित्रण को संसाधित करने से रोकती है।
UI थ्रेड पर निष्पादित समकालिक HTTP अनुरोध शुरुआती डेवलपर्स में ANR का सबसे आम कारण है। सर्वर पर एक त्वरित अनुरोध में भी 1–3 सेकंड लग सकते हैं, और खराब कनेक्शन पर — 30 सेकंड या अधिक। Android API 11 से मुख्य थ्रेड पर नेटवर्क प्रक्रियाओं को स्पष्ट रूप से प्रतिबंधित करता है, NetworkOnMainThreadException फेंकता है।
एसिंक्रोनस कॉल के लिए Coroutines या RxJava का उपयोग करें। Dispatchers.IO डिस्पैचर के साथ कोरूटीन बैकग्राउंड थ्रेड पर अनुरोध निष्पादित करती हैं और परिणाम Dispatchers.Main के माध्यम से मुख्य थ्रेड पर भेजती हैं। यह नेटवर्क प्रक्रियाओं द्वारा UI थ्रेड ब्लॉकिंग को पूरी तरह से समाप्त करता है।
fun fetchUserData() {
CoroutineScope(Dispatchers.Main).launch {
val result = withContext(Dispatchers.IO) {
api.getUserData() // बैकग्राउंड ऑपरेशन
}
updateUI(result) // मुख्य थ्रेड पर परिणाम
}
}
बड़े डेटा ऐरे को संसाधित करना, JSON या XML पार्स करना, सीधे मुख्य थ्रेड पर bitmap के साथ काम करना — ANR का दूसरा सबसे आम कारण। ईवेंट लूप में वापस आए बिना UI थ्रेड के 300 मिलीसेकंड निरंतर काम करने से भी रेंडरिंग में ध्यान देने योग्य देरी होती है, और 5 सेकंड की सीमा ANR के रूप में दर्ज की जाती है।
WorkManager और बैकग्राउंड सेवाएँ भारी गणनाओं को मुख्य थ्रेड से हटाने के लिए डिज़ाइन की गई हैं। UI को ब्लॉक किए बिना डेटा को खंडों में पास करने के लिए AsyncTask (पुराना), ListenableFuture या Kotlin Flow का उपयोग करें।
Deadlock तब होता है जब दो थ्रेड लॉक रखते हैं और एक-दूसरे की प्रतीक्षा करते हैं। यदि थ्रेड में से एक मुख्य थ्रेड है, तो सिस्टम ठीक 5 सेकंड के बाद ANR दर्ज करता है। UI थ्रेड से कॉल किए गए Thread.join(), CountDownLatch.await() और synchronized ब्लॉक ब्लॉकिंग का जोखिम रखते हैं।
मुख्य थ्रेड पर किसी भी ब्लॉकिंग प्रक्रिया से बचें। synchronized के बजाय ConcurrentHashMap का उपयोग करें; Thread.join() के बजाय async/await के साथ कोरूटीन का उपयोग करें। यह नियम Android में किसी भी भाषा पर लागू होता है: Java, Kotlin या JNI के माध्यम से C++।
BroadcastReceiver डिफ़ॉल्ट रूप से मुख्य थ्रेड पर चलता है। यदि onReceive() 10 सेकंड से अधिक व्यस्त है, तो Android ANR दिखाता है। onReceive के अंदर डेटाबेस या नेटवर्क से डेटा लोड करना फ्रीज़ का गारंटीशुदा रास्ता है।
बैकग्राउंड थ्रेड पर स्विच करने के लिए BroadcastReceiver के अंदर goAsync() का उपयोग करें, या getBackgroundBroadcastReceiver() के साथ registerReceiver का उपयोग करें। यह UI को ब्लॉक किए बिना ईवेंट को संसाधित करने की अनुमति देता है।
ContentProvider के लिए भारी क्वेरी या UI थ्रेड पर SQLite के साथ सीधा काम — ANR का कम स्पष्ट लेकिन सामान्य कारण। डेटाबेस माइग्रेशन या हज़ारों रिकॉर्ड के बल्क इंसर्शन के दौरान, निष्पादन समय 5 सेकंड की सीमा से अधिक हो सकता है।
सभी डेटाबेस प्रक्रियाओं को suspend फ़ंक्शन के साथ Room के माध्यम से बैकग्राउंड थ्रेड पर ले जाएँ। Room स्वचालित रूप से जाँचता है कि क्वेरी मुख्य थ्रेड पर निष्पादित नहीं हो रही है और उल्लंघन होने पर अपवाद फेंकता है।
ANR का निदान सामान्य अपवादों को डीबग करने से अलग है — आप try-catch ब्लॉक में ANR नहीं पकड़ सकते। जानकारी का मुख्य स्रोत traces.txt फ़ाइल है, जिसे Android फ्रीज़ के समय बनाता है।
traces.txt में ANR के समय सभी ऐप थ्रेड्स का कॉल स्टैक होता है। वास्तविक डिवाइस से फ़ाइल पढ़ने के लिए, adb bugreport कमांड चलाएँ, जो हाल की सभी ANR सहित पूर्ण सिस्टम रिपोर्ट एकत्र करता है। एमुलेटर के लिए, फ़ाइल /data/anr/traces.txt पर उपलब्ध है। कॉल स्टैक दिखाता है कि ब्लॉकिंग के समय मुख्य थ्रेड पर कौन सी विधि निष्पादित हो रही थी।
adb bugreport bugreport.zip
unzip -p bugreport.zip "*traces*" > traces.txt
Google Play Console एकत्रित रिपोर्ट और त्रुटि आवृत्तियों के साथ ANR & Crash अनुभाग प्रदान करता है। प्रत्येक ANR के लिए, कॉल स्टैक और डिवाइस आँकड़े दिखाए जाते हैं: मॉडल, Android संस्करण, क्षेत्र। यह उन ANR की पहचान करने की अनुमति देता है जो विशिष्ट डिवाइस या सिस्टम संस्करणों पर निर्भर करते हैं।
Android Studio 2021 से प्रोफाइलर में ANR Watchdog शामिल है। यह स्वचालित रूप से थ्रेड डंप रिकॉर्ड करता है यदि मुख्य थ्रेड सीमा समय से अधिक प्रतिक्रिया नहीं देता है। उपकरण ईवेंट की समयरेखा दिखाता है: कौन सी प्रक्रियाएँ शुरू हुईं, कौन सी विधियाँ निष्पादित हुईं, और किस चरण में ब्लॉकिंग हुई।
ANR की रोकथाम एक मौलिक नियम पर आधारित है: मुख्य थ्रेड को केवल UI ईवेंट को संभालना चाहिए। 16 मिलीसेकंड (एक फ्रेम का समय) से अधिक लंबी कोई भी प्रक्रिया बैकग्राउंड थ्रेड पर चलनी चाहिए।
StrictMode विकास के दौरान संभावित ANR का पता लगाने के लिए Android का अंतर्निर्मित उपकरण है। इसे डिस्क और नेटवर्क प्रक्रियाओं के लिए फ़्लैग के साथ Application.onCreate() में सक्षम करें। उल्लंघन होने पर, StrictMode अपवाद फेंकता है या logcat में लिखता है।
if (BuildConfig.DEBUG) {
StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyLog()
.build()
.let { StrictMode.setThreadPolicy(it) }
}
Kotlin Coroutines — आधुनिक Android ऐप में एसिंक्रोनस काम का मानक तरीका। मुख्य दृष्टिकोण: I/O प्रक्रियाएँ Dispatchers.IO पर चलती हैं, परिणाम UI अपडेट के लिए Dispatchers.Main पर भेजा जाता है। Flow जैसे परिदृश्यों के लिए, CPU-गहन कार्यों के लिए Dispatchers.Default का उपयोग करें।
RxJava पुराने प्रोजेक्ट में लोकप्रिय बना हुआ है। subscribeOn(Schedulers.io()) और observeOn(AndroidSchedulers.mainThread()) — ANR को रोकने के लिए न्यूनतम सेट। मुख्य नियम वही है: कोई भी Observable या Flowable मुख्य थ्रेड से डेटा उत्सर्जित नहीं करना चाहिए।
Firebase Crashlytics SDK संस्करण 18.4.0 से ANR निगरानी को बॉक्स से बाहर समर्थन करता है। Android 11+ के लिए, Crashlytics सिस्टम API ApplicationExitInfo का उपयोग करता है, जो सटीक समाप्ति कारण प्रदान करता है: ANR, Crash, या सिस्टम किल। प्रासंगिक विश्लेषण के लिए स्क्रीन और स्थिति पैरामीटर के साथ कस्टम कुंजियाँ सक्षम करें।
पाँच उपकरण ANR के साथ काम करने के सभी चरणों को कवर करते हैं: वर्कस्टेशन पर डीबगिंग से लेकर उत्पादन में निगरानी तक। प्रत्येक उपकरण अपना कार्य हल करता है और विभिन्न परिदृश्यों के लिए डेटा प्रदान करता है।
| उपकरण | उद्देश्य | डेटा प्रारूप |
|---|---|---|
| StrictMode | विकास के दौरान पता लगाना | Logcat / Exception |
| ANR Watchdog (Android Studio) | रीयल-टाइम ट्रेसिंग | Thread dump + timeline |
| Google Play Console | एकत्रित आँकड़े | ANR rate + stack traces |
| Firebase Crashlytics | उत्पादन निगरानी | ApplicationExitInfo |
| adb bugreport | पूर्ण सिस्टम रिपोर्ट | traces.txt + logcat + dmesg |
प्रत्येक उपकरण का अपना क्षेत्र है: StrictMode शुरुआती चरणों में स्पष्ट उल्लंघनों को पकड़ता है, Crashlytics उपयोगकर्ताओं के बीच वास्तविक ANR आवृत्ति दिखाता है, और adb bugreport जटिल मामलों के लिए सबसे पूर्ण चित्र प्रदान करता है। पूर्ण कवरेज के लिए उन्हें संयोजित करें।
Firebase Performance UI थ्रेड प्रतिक्रिया समय को ट्रैक करता है और संदिग्ध रूप से लंबी प्रक्रियाओं के लिए स्वचालित रूप से ट्रेस बनाता है। यदि मुख्य थ्रेड 500 मिलीसेकंड से अधिक समय तक ब्लॉक होता है, तो Performance दोषी विधि के नाम के साथ एक कस्टम ट्रेस रिकॉर्ड करता है। यह उपयोगकर्ता की भागीदारी के बिना और महत्वपूर्ण होने से पहले ANR परिदृश्यों का पता लगाने की अनुमति देता है।
Firebase Crashlytics के साथ एकीकरण पूरी तस्वीर देता है: Performance ANR से पहले धीमापन दिखाता है, और Crashlytics फ्रीज़ को दिखाता है। Firebase Console में ANR दर 0.1% से अधिक होने पर अलर्ट सेट करें, और आपको सामूहिक उपयोगकर्ता शिकायतों से पहले नई समस्याओं के बारे में सूचनाएँ प्राप्त होंगी।
अक्सर पूछे जाने वाले प्रश्न
ANR एक फ्रीज़ है जहाँ ऐप प्रतिक्रिया नहीं देता लेकिन मेमोरी में रहता है। Crash प्रक्रिया से बाहर निकलने के साथ पूर्ण असामान्य समाप्ति है। ANR से “बचा जा सकता है” यदि सिस्टम या उपयोगकर्ता प्रतिक्रिया की प्रतीक्षा करता है, जबकि Crash हमेशा ऐप को समाप्त करता है।
नहीं। ANR Java/Kotlin अपवाद नहीं है, बल्कि प्रक्रिया स्तर पर एक सिस्टम सिग्नल (SIGQUIT) है। डेवलपर इसे ऐप कोड में संभाल नहीं सकता। ANR पर प्रतिक्रिया करने का एकमात्र तरीका पुनरारंभ के बाद रिपोर्ट का विश्लेषण करना है।
डिवाइस प्रदर्शन, Android संस्करण, CPU लोड और बैकग्राउंड प्रक्रियाओं की संख्या ANR की संभावना को प्रभावित करती है। कमजोर उपकरणों पर, वही प्रक्रिया 2–3 गुना अधिक समय ले सकती है, 5 सेकंड की सीमा से अधिक।
सामान्य BroadcastReceiver के लिए onReceive() में 10 सेकंड। Foreground सेवाओं के लिए, सीमा 20 सेकंड है, और ContentProvider के लिए — कोई स्पष्ट सीमा नहीं है, लेकिन मुख्य थ्रेड को 5 सेकंड से अधिक ब्लॉक करना फिर भी ANR का कारण बनता है।
सभी डीबग बिल्ड में StrictMode सक्षम करें, Firebase Crashlytics के माध्यम से निगरानी जोड़ें, और जब ANR हो तो adb bugreport का उपयोग करें। अनियमित ANR अक्सर रेस कंडीशन या विशिष्ट नेटवर्क स्थितियों से संबंधित होते हैं।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें