ANR की गड़बड़ियों का पता लगाना और उन्हें ठीक करना

जब किसी Android ऐप्लिकेशन का यूज़र इंटरफ़ेस (यूआई) थ्रेड लंबे समय तक ब्लॉक रहता है, तो सिस्टम "ऐप्लिकेशन काम नहीं कर रहा है" (ANR) की गड़बड़ी. इस पेज पर, अलग-अलग प्लैटफ़ॉर्म के बारे में बताया गया है एएनआर के टाइप, उनकी गड़बड़ी की जांच करने का तरीका, और उन्हें ठीक करने के सुझाव. सभी सूची में शामिल डिफ़ॉल्ट टाइम आउट की समयसीमा, AOSP और Pixel डिवाइसों के लिए है; ये समय OEM के हिसाब से तय हो सकता है.

ध्यान रखें कि ANR की गड़बड़ी की वजह का पता लगाते समय, इन बातों का ध्यान रखें: सिस्टम और ऐप्लिकेशन की समस्याओं के बीच अंतर कर सकता है.

सिस्टम के खराब स्टेटस में होने पर, ANR की ये समस्याएं हो सकती हैं:

  • सिस्टम सर्वर में अस्थायी समस्याएं होने की वजह से आम तौर पर, फ़ास्ट बाइंडर कॉल धीमा.
  • सिस्टम सर्वर से जुड़ी समस्याओं और डिवाइस पर लोड ज़्यादा होने की वजह से ऐप्लिकेशन थ्रेड नहीं खुल रहे हैं शेड्यूल किया गया है.

अगर आपके लिए उपलब्ध है, तो सिस्टम और ऐप्लिकेशन की समस्याओं के बीच अंतर करने का सबसे अच्छा तरीका यह है परफ़ेटो ट्रेस इस्तेमाल करने के लिए:

  • थ्रेड की स्थिति को देखकर पता लगाएं कि ऐप्लिकेशन का मुख्य थ्रेड शेड्यूल किया गया है या नहीं ट्रैक कर सकते हैं कि वह चल रहा है या नहीं.
  • लॉक के विवाद जैसी समस्याओं के लिए, system_server थ्रेड देखें.
  • धीमे बाइंडर कॉल के लिए, अगर जवाब थ्रेड मौजूद है, तो उसकी वजह जानने के लिए जवाब थ्रेड पर नज़र डालें धीमा.

इनपुट भेजने का समय खत्म हो गया

इनपुट डिस्पैच ANR की गड़बड़ी तब होती है, जब ऐप्लिकेशन का मुख्य थ्रेड, किसी इनपुट का जवाब नहीं देता है जैसे कि स्वाइप या बटन दबाना. ऐप्लिकेशन फ़ोरग्राउंड में चालू है जब इनपुट डिस्पैच टाइम आउट होते हैं, तो वे उपयोगकर्ता को करीब-करीब हमेशा दिखते हैं और उसे कम करना बहुत ज़रूरी है.

डिफ़ॉल्ट टाइम आउट की अवधि: पांच सेकंड.

इनपुट डिसपैच ANR आम तौर पर, मुख्य थ्रेड में मौजूद समस्याओं की वजह से होता है. अगर मुख्य लॉक पाने के लिए थ्रेड ब्लॉक की गई थी. होल्डर थ्रेड भी शामिल हैं.

मैसेज भेजे जाने से जुड़ी ANR की समस्याओं से बचने के लिए, ये सबसे सही तरीके अपनाएं:

  • मुख्य थ्रेड पर, ब्लॉक करने या लंबे समय तक चलने वाली कार्रवाइयां न करें. इन बातों पर ध्यान दें StrictMode का इस्तेमाल गलती से किया गया है गतिविधि देखी है.
  • मुख्य थ्रेड और अन्य थ्रेड के बीच लॉक के विवाद को कम से कम करें.
  • मुख्य थ्रेड पर, बिना यूज़र इंटरफ़ेस (यूआई) के काम को कम से कम करें. जैसे, ब्रॉडकास्ट को मैनेज करते समय या चालू सेवाएं.

सामान्य वजहें

इनपुट डिसपैच ANR के लिए यहां कुछ सामान्य वजहें और सुझाए गए सुधार दिए गए हैं.

वजह क्या होता है सुझाए गए सुधार
धीमा बाइंडर कॉल मुख्य थ्रेड एक लंबा सिंक्रोनस बाइंडर कॉल करता है. कॉल को मुख्य थ्रेड से बाहर ले जाएं या अगर आपको कॉल को ऑप्टिमाइज़ करना है, तो वह एपीआई का मालिक है.
लगातार कई बाइंडर कॉल मुख्य थ्रेड की मदद से, लगातार कई सिंक्रोनस बाइंडर कॉल किए जा सकते हैं. बार-बार बाइंडर कॉल न करें.
I/O को ब्लॉक करना मुख्य थ्रेड, I/O कॉल को ब्लॉक करने की सुविधा देती है, जैसे कि डेटाबेस या नेटवर्क ऐक्सेस दें. ब्लॉक करने वाले सभी IO को मुख्य थ्रेड से बाहर ले जाएं.
लॉक करने से जुड़ा विवाद लॉक मिलने के इंतज़ार में, मुख्य थ्रेड को ब्लॉक कर दिया गया है. मुख्य थ्रेड और अन्य थ्रेड के बीच लॉक का विवाद कम करें. दूसरे थ्रेड में, धीमे कोड को ऑप्टिमाइज़ करें.
महंगा फ़्रेम एक ही फ़्रेम में बहुत ज़्यादा रेंडर होने से, बहुत ज़्यादा झंझट हुई. फ़्रेम पर कम मेहनत करके काम करें. n2 एल्गोरिदम का इस्तेमाल न करें. इस्तेमाल की जाने वाली चीज़ें के लिए कॉम्पोनेंट का इस्तेमाल करते हैं, जैसे कि स्क्रोल या पेजिंग. जेटपैक पेजिंग लाइब्रेरी.
किसी दूसरे कॉम्पोनेंट ने ब्लॉक किया ब्रॉडकास्ट रिसीवर जैसा कोई दूसरा कॉम्पोनेंट चल रहा है और मुख्य थ्रेड को ब्लॉक कर रही हूँ. जहां तक हो सके, नॉन-यूज़र इंटरफ़ेस (यूआई) के काम को मुख्य थ्रेड से बाहर ले जाएं. ब्रॉडकास्ट चलाएं पाने वाले किसी दूसरे थ्रेड पर.
जीपीयू हैंग जीपीयू हैंग एक सिस्टम या हार्डवेयर की समस्या है, जिसकी वजह से रेंडर करने की प्रोसेस को ब्लॉक किया जाएगा. इसलिए, ANR की गड़बड़ी को इनपुट किया जाएगा. माफ़ करें, आम तौर पर ऐप्लिकेशन में कोई सुधार नहीं किया जा सकता. अगर आपने तो इस समस्या को हल करने के लिए हार्डवेयर टीम से संपर्क करें.

डीबग करने का तरीका

Google Play में ANR क्लस्टर के सिग्नेचर को देखकर, डीबग करने की प्रक्रिया शुरू करें Console या Firebase Crashlytics पर जाएं. क्लस्टर में आम तौर पर पेज के सबसे ऊपरी हिस्से में वे फ़्रेम जिनमें ANR की गड़बड़ी हो सकती है.

नीचे दिया गया फ़्लो चार्ट, इनपुट टाइम आउट की वजह पता करने का तरीका बताता है डिस्पैच ANR.

पहली इमेज. इनपुट डिसपैच एएनआर को डीबग करने का तरीका.

Play की ज़रूरी जानकारी, ANR की इन आम वजहों का पता लगा सकती है और उन्हें डीबग करने में मदद कर सकती है. इसके लिए उदाहरण के लिए, अगर ज़रूरी जानकारी को पता चलता है कि ANR की समस्या, लॉक किए जाने की वजह से हुई है, तो यह ANR इनसाइट सेक्शन में, समस्या और उसे ठीक करने का सुझाव दिया जा सकता है.

दूसरी इमेज. Play की ज़रूरी जानकारी में ANR का पता लगाना.

फ़ोकस की गई कोई विंडो नहीं है

जब टच जैसे इवेंट, हिट के आधार पर सीधे सही विंडो पर भेजे जाते हैं की टेस्टिंग के दौरान, 'की' जैसे इवेंट के लिए टारगेट की ज़रूरत होती है. इस टारगेट को फ़ोकस विंडो चुनें. हर डिसप्ले पर, फ़ोकस वाली सिर्फ़ एक विंडो होती है. यह आम तौर पर होती है वह विंडो जिससे उपयोगकर्ता फ़िलहाल इंटरैक्ट कर रहा है. अगर फ़ोकस की गई विंडो पर कोई विंडो नहीं मिलती, तो इनपुट पर नो-फ़ोकस-विंडो एएनआर दिखता है. विंडो पर फ़ोकस न करने वाला ANR एक तरह का इनपुट डिस्पैच ANR है.

डिफ़ॉल्ट टाइम आउट की अवधि: पांच सेकंड.

सामान्य वजहें

विंडो पर फ़ोकस नहीं करने वाले ANR, आम तौर पर इनमें से किसी एक समस्या की वजह से होते हैं:

  • ऐप्लिकेशन बहुत ज़्यादा काम कर रहा है और पहला फ़्रेम बनाने के लिए बहुत धीमा है.
  • मुख्य विंडो पर फ़ोकस नहीं किया जा सकता. अगर किसी विंडो को FLAG_NOT_FOCUSABLE, उपयोगकर्ता इसे कुंजी या बटन इवेंट नहीं भेज सकता.

Kotlin

override fun onCreate(savedInstanceState: Bundle) {
  super.onCreate(savedInstanceState)
  setContentView(R.layout.activity_main)
  window.addFlags(WindowManager.LayoutParams.FLAG_FLAG_NOT_FOCUSABLE)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
}

ब्रॉडकास्ट रिसीवर का टाइम आउट

ब्रॉडकास्ट रिसीवर में ANR की गड़बड़ी तब होती है, जब ब्रॉडकास्ट रिसीवर समय पर ब्रॉडकास्ट करें. सिंक्रोनस रिसीवर या कॉल न करने वाले रिसीवर के लिए goAsync(), टाइम आउट का मतलब है कि onReceive() पूरे नहीं हुआ समय. एक साथ काम नहीं करने वाले रिसीवर या goAsync() पर कॉल करने वाले लोगों के लिए, टाइम आउट का मतलब है PendingResult.finish() को समय पर कॉल नहीं किया गया.

ब्रॉडकास्ट रिसीवर के ANR अक्सर इन थ्रेड में होते हैं:

  • मुख्य थ्रेड, अगर समस्या धीरे-धीरे ऐप्लिकेशन शुरू होने की है.
  • अगर समस्या धीमा onReceive() कोड की है, तो थ्रेड में ब्रॉडकास्ट रिसीवर का इस्तेमाल किया जा रहा है.
  • अगर समस्या धीमा है, तो goAsync() का ब्रॉडकास्ट कोड धीमा होने पर, कर्मचारियों के थ्रेड ब्रॉडकास्ट करें.

ब्रॉडकास्ट रिसीवर की ANR से जुड़ी गड़बड़ियों से बचने के लिए, यहां दिए गए सबसे सही तरीके अपनाएं:

  • पक्का करें कि ऐप्लिकेशन का स्टार्टअप तेज़ हो, क्योंकि ANR टाइम आउट में इसे गिना जाता है, अगर ऐप्लिकेशन, ब्रॉडकास्ट को हैंडल करना शुरू कर दे.
  • अगर goAsync() का इस्तेमाल किया गया है, तो पक्का करें कि PendingResult.finish() को तुरंत कॉल किया गया हो. ऐसा सिंक्रोनस ब्रॉडकास्ट रिसीवर की तरह ही ANR वाली गड़बड़ी की वजह से होता है.
  • अगर goAsync() का इस्तेमाल किया जाता है, तो पक्का करें कि वर्कर थ्रेड को लंबे समय तक चलने वाले या ब्लॉक करने के अन्य ऑपरेशन.
  • इस ब्राउज़र में ब्रॉडकास्ट रिसीवर चलाने के लिए registerReceiver() का इस्तेमाल करें मुख्य थ्रेड में चल रहे यूज़र इंटरफ़ेस (यूआई) कोड को ब्लॉक होने से बचाने के लिए, नॉन-मेन थ्रेड.

टाइम आउट की अवधि

ब्रॉडकास्ट मैसेज के टाइम आउट होने की अवधि, इस बात पर निर्भर करती है कि फ़ोरग्राउंड इंटेंट के फ़्लैग का इस्तेमाल किया जा रहा है या नहीं सेट है और प्लैटफ़ॉर्म वर्शन है.

इंटेंट का टाइप Android 13 और उससे पहले वाले वर्शन के लिए Android 14 और उसके बाद के वर्शन के लिए

फ़ोरग्राउंड प्राथमिकता का इंटेंट

(FLAG_RECEIVER_FOREGROUND सेट)

10 सेकंड

10 से 20 सेकंड. यह इस बात पर निर्भर करता है कि प्रोसेस में सीपीयू का इस्तेमाल किया गया है या नहीं

बैकग्राउंड प्राथमिकता इंटेंट

(FLAG_RECEIVER_FOREGROUND सेट नहीं है)

60 सेकंड

60-120 सेकंड, इस बात पर निर्भर करता है कि प्रोसेस सीपीयू-स्टार है या नहीं

FLAG_RECEIVER_FOREGROUND फ़्लैग सेट है या नहीं, यह बताने के लिए "flg=" को खोजें में ANR की गड़बड़ी का पता लगाएं और 0x10000000 की मौजूदगी देखें. अगर यह बिट सेट है, तो इंटेंट में FLAG_RECEIVER_FOREGROUND सेट है और इसलिए टाइम आउट कम है.

ANR वाली गड़बड़ी का उदाहरण, जिसमें ब्रॉडकास्ट का टाइम आउट (10-20 सेकंड) कम हो:

Broadcast of Intent { act=android.inent.action.SCREEN_ON flg=0x50200010 }

ANR वाली गड़बड़ी के विषय का उदाहरण, जिसके ब्रॉडकास्ट का टाइम आउट (60-120 सेकंड) ज़्यादा है:

Broadcast of Intent { act=android.intent.action.TIME_SET flg=0x25200010 }

ब्रॉडकास्ट का समय कैसे मापा जाता है

ब्रॉडकास्ट की अवधि तब मापी जाती है, जब ब्रॉडकास्ट को ब्रॉडकास्ट भेजा जाता है system_server को ऐप्लिकेशन के लिए जोड़ा जाता है और जब ऐप्लिकेशन, ब्रॉडकास्ट. अगर ऐप्लिकेशन की प्रोसेस पहले से नहीं चल रही थी, तो इसे भी ठंडा करना होगा ANR वाली गड़बड़ी की समयावधि के दौरान शुरू हो सकता है. इसलिए, ऐप्लिकेशन के धीरे-धीरे शुरू होने की वजह से, ब्रॉडकास्ट रिसीवर के एएनआर.

नीचे दिए गए डायग्राम में दिखाया गया है कि ब्रॉडकास्ट रिसीवर ANR की टाइमलाइन किस तरह से अलाइन होती है कुछ ऐप्लिकेशन प्रोसेस भी शामिल हैं.

तीसरी इमेज. ब्रॉडकास्ट रिसीवर की ANR टाइमलाइन.

डेटा मिलने की प्रोसेस पूरी होने के बाद, ANR वाली गड़बड़ी का टाइम आउट मेज़रमेंट खत्म हो जाता है ब्रॉडकास्ट: यह इस बात पर निर्भर करता है कि असल में ऐसा कब होता है. यह इस बात पर निर्भर करता है कि एसिंक्रोनस रिसीवर.

  • सिंक्रोनस रिसीवर के लिए, onReceive() के वापस आने पर मेज़रमेंट बंद हो जाता है.
  • एसिंक्रोनस रिसीवर के लिए मेज़रमेंट तब बंद हो जाता है, जब PendingResult.finish() पर कॉल किया गया है.
चौथी इमेज. सिंक्रोनस के लिए ANR टाइमआउट मेज़रमेंट एंडपॉइंट और एसिंक्रोनस रिसीवर

सामान्य वजहें

यहां ब्रॉडकास्ट रिसीवर के ANRs से जुड़ी कुछ आम वजहें बताई गई हैं. साथ ही, इन्हें ठीक करने के सुझाव भी दिए गए हैं.

वजह Applies to समस्या क्या थी सुझाया गया हल
ऐप्लिकेशन शुरू होने की रफ़्तार कम है सभी रिसीवर ऐप्लिकेशन को कोल्ड स्टार्ट करने में बहुत ज़्यादा समय लगा. ऐप्लिकेशन शुरू होने के बाद, उसे तेज़ी से चालू होने के लिए ऑप्टिमाइज़ करें.
onReceive() शेड्यूल नहीं किया गया है सभी रिसीवर ब्रॉडकास्ट रिसीवर थ्रेड कोई दूसरा काम करने में व्यस्त था. इसलिए, वह दूसरे काम नहीं कर सका onReceive() तरीका शुरू करें. परफ़ॉर्म न करें रिसीवर थ्रेड पर लंबे समय तक चलने वाले टास्क (या रिसीवर को खास तरह के इवेंट पर ले जाएं) थ्रेड).
onReceive() ठीक से काम नहीं कर रहा है पैसे पाने वाले सभी लोग, लेकिन मुख्य रूप से सिंक्रोनस onReceive() तरीका शुरू हो गया, लेकिन ब्लॉक या धीमी थी इसलिए समय पर पूरा नहीं हुआ. धीरे ऑप्टिमाइज़ करें पाने वाले का कोड.
एक साथ काम नहीं करने वाले रिसीवर के टास्क शेड्यूल नहीं किए गए goAsync() अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है रिसीवर onReceive() तरीके से काम पूरा करने की कोशिश की गई काम शुरू नहीं हुआ. धीमे कॉल या ब्लॉक होने वाले कॉल को ऑप्टिमाइज़ करें या ब्रॉडकास्ट के लिए अलग-अलग थ्रेड इस्तेमाल करें कर्मचारी बनाम लंबे समय तक चलने वाले अन्य टास्क.
काम करने वाले लोग धीमा चल रहे हैं या ब्लॉक हैं goAsync() रिसीवर वर्कर थ्रेड में, किसी जगह पर ब्लॉक किया जा रहा था या धीमी गति से कार्रवाई हो रही थी पूल की ओर ले जाने की सुविधा देता है. इसलिए, PendingResult.finish समय पर कॉल नहीं किया गया. धीमे async रिसीवर को ऑप्टिमाइज़ करें कोड.
PendingResult.finish को कॉल करना भूल गए goAsync() रिसीवर कोड पाथ में, finish() पर किया गया कॉल मौजूद नहीं है. पक्का करें कि finish() को हमेशा कॉल किया जाए.

डीबग करने का तरीका

क्लस्टर सिग्नेचर और ANR रिपोर्ट के आधार पर, उस थ्रेड का पता लगाया जा सकता है जिसमें पाने वाला चालू होता है और फिर वह कोड जो मौजूद नहीं है या चल रहा है धीरे-धीरे.

नीचे दिया गया फ़्लो चार्ट, ब्रॉडकास्ट की वजह पता करने का तरीका बताता है रिसीवर ANR.

पांचवीं इमेज. ब्रॉडकास्ट रिसीवर ANR की गड़बड़ी को कैसे डीबग करें.

रिसीवर कोड ढूंढना

Google Play Console, ANR की गड़बड़ी में, रिसीवर की क्लास और ब्रॉडकास्ट इंटेंट दिखाता है हस्ताक्षर करें. इसके लिए, यह देखें:

  • cmp=<receiver class>
  • act=<broadcast_intent>

यहां ब्रॉडकास्ट रिसीवर के ANR सिग्नेचर का एक उदाहरण दिया गया है:

com.example.app.MyClass.myMethod
Broadcast of Intent { act=android.accounts.LOGIN_ACCOUNTS_CHANGED
cmp=com.example.app/com.example.app.MyAccountReceiver }

onReceive() तरीके से चलने वाला थ्रेड ढूंढें

अगर कस्टम हैंडलर की जानकारी देने के लिए Context.registerReceiver का इस्तेमाल किया जा रहा है, तो यही वह थ्रेड है जो इस हैंडलर को चला रहा है. अगर ऐसा नहीं है, तो यह मुख्य थ्रेड है.

उदाहरण: एक साथ काम नहीं करने वाले रिसीवर के टास्क शेड्यूल नहीं किए गए

इस सेक्शन में एक उदाहरण दिया गया है. इसमें ब्रॉडकास्ट रिसीवर ANR को डीबग करने का तरीका बताया गया है.

मान लें कि ANR सिग्नेचर कुछ ऐसा दिखता है:

com.example.app.MyClass.myMethod
Broadcast of Intent {
act=android.accounts.LOG_ACCOUNTS_CHANGED cmp=com.example.app/com.example.app.MyReceiver }

हस्ताक्षर के आधार पर ऐसा लगता है कि ब्रॉडकास्ट का इंटेंट android.accounts.LOG_ACCOUNTS_CHANGED और पैसे पाने वाले व्यक्ति की क्लास com.example.app.MyReceiver.

रिसीवर कोड की मदद से, यह तय किया जा सकता है कि थ्रेड पूल में "BG Thread नेटवर्क" मौजूद है या नहीं [0,1,2,3]" इस ब्रॉडकास्ट को प्रोसेस करने का मुख्य काम करता है. स्टैक में देखा जा रहा है डंप किया है, तो आप देख सकते हैं कि सभी चार बैकग्राउंड (BG) थ्रेड का पैटर्न एक जैसा है: वह ब्लॉक करने वाला getDataSync कॉल चला रहा है. BG के सभी थ्रेड व्यस्त थे, इसलिए ब्रॉडकास्ट को समय पर प्रोसेस नहीं किया जा सका. इस वजह से ANR की गड़बड़ी हुई.

BG Thread #0 (tid=26) Waiting

at jdk.internal.misc.Unsafe.park(Native method:0)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture:563)
at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture:68)
at com.example.app.getDataSync(<MyClass>:152)

...

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
at com.google.android.libraries.concurrent.AndroidExecutorsModule.lambda$withStrictMode$5(AndroidExecutorsModule:451)
at com.google.android.libraries.concurrent.AndroidExecutorsModule$$ExternalSyntheticLambda8.run(AndroidExecutorsModule:1)
at java.lang.Thread.run(Thread.java:1012)
at com.google.android.libraries.concurrent.ManagedPriorityThread.run(ManagedPriorityThread:34)

There are several approaches to fix the issue:

  • Find out why getDataSync is slow and optimize.
  • Don't run getDataSync on all four BG threads.
  • More generally, ensure that the BG thread pool isn't saturated with long-running operations.
  • Use a dedicated thread pool for goAsync worker tasks.
  • Use an unbounded thread pool instead of the bounded BG thread pool

Example: slow app startup

A slow app startup can cause several types of ANRs, especially broadcast receiver and execute service ANRs. The cause of an ANR is likely slow app startup if you see ActivityThread.handleBindApplication in the main thread stacks.

Execute service timeout

An execute service ANR happens when the app's main thread doesn't start a service in time. Specifically, a service doesn't finish executing onCreate() and onStartCommand() or onBind() within the timeout period.

Default timeout period: 20 seconds for foreground service; 200 seconds for background service. The ANR timeout period includes the app cold start, if necessary, and calls to onCreate(), onBind(), or onStartCommand().

To avoid execute service ANRs, follow these general best practices:

  • Make sure that app startup is fast, since it's counted in the ANR timeout if the app is started to run the service component.
  • Make sure that the service's onCreate(), onStartCommand(), and onBind() methods are fast.
  • Avoid running any slow or blocking operations on the main thread from other components; these operations can prevent a service from starting quickly.

Common causes

The following table lists common causes of execute service ANRs and suggested fixes.

Cause What Suggested fix
Slow app startup The app takes too long to perform a cold start. Optimize slow app start.
Slow onCreate(), onStartCommand(), or onBind() The service component's onCreate(), onStartCommand(), or onBind() method takes too long to execute on the main thread. Optimize slow code. Move slow operations off the critical path where possible.
Not scheduled (main thread blocked before onStart()) The app's main thread is blocked by another component before the service can be started. Move other component's work off the main thread. Optimize other component's blocking code.

How to debug

From the cluster signature and ANR report in Google Play Console or Firebase Crashlytics, you can often determine the cause of the ANR based on what the main thread is doing.

The following flow chart describes how to debug an execute service ANR.

Figure 6. How to debug an execute service ANR.

If you've determined that the execute service ANR is actionable, follow these steps to help resolve the issue:

  1. Find the service component class in the ANR signature. In Google Play Console, the service component class is shown in the ANR signature. In the following example ANR details, it's com.example.app/MyService.

    com.google.common.util.concurrent.Uninterruptibles.awaitUninterruptibly
    Executing service com.example.app/com.example.app.MyService
    
  2. Determine whether the slow or block operation is part of app startup, the service component, or elsewhere by checking for the following important function call(s) in the main threads.

    Function call(s) in main thread stacks What it means
    android.app.ActivityThread.handleBindApplication App was starting up, so the ANR was caused by slow app start.

    <ServiceClass>.onCreate()

    [...]

    android.app.ActivityThread.handleCreateService

    Service was being created, so the ANR was likely caused by slow onCreate() code.

    <ServiceClass>.onBind()

    [...]

    android.app.ActivityThread.handleBindService

    Service was being bound, so the ANR was likely caused by slow onBind() code.

    <ServiceClass>.onStartCommand()

    [...]

    android.app.ActivityThread.handleServiceArgs

    Service was being started, so the ANR was likely caused by slow onStartCommand() code.

    For example, if the onStartCommand() method in the MyService class is slow, the main threads will look like this:

    at com.example.app.MyService.onStartCommand(FooService.java:25)
    at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4820)
    at android.app.ActivityThread.-$$Nest$mhandleServiceArgs(unavailable:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2289)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:205)
    at android.os.Looper.loop(Looper.java:294)
    at android.app.ActivityThread.main(ActivityThread.java:8176)
    at java.lang.reflect.Method.invoke(Native method:0)
    

    अगर आपको कोई भी ज़रूरी फ़ंक्शन कॉल नहीं दिख रहा है, तो ऐसे में कुछ अन्य संभावनाएं:

    • सेवा चालू या बंद हो रही है. इसका मतलब है कि स्टैक काफ़ी देर से लिया गया. इस स्थिति में, एएनआर को फ़ॉल्स पॉज़िटिव के तौर पर अनदेखा किया जा सकता है.
    • कोई दूसरा ऐप्लिकेशन कॉम्पोनेंट चल रहा है, जैसे कि ब्रॉडकास्ट रिसीवर. इसमें मुमकिन है कि इस कॉम्पोनेंट में मुख्य थ्रेड ब्लॉक हो जाए. इसकी वजह से, से सेवा शुरू कर दी है.
  3. अगर आपको कुंजी के फ़ंक्शन का कोई कॉल दिखता है और यह पता किया जा सकता है कि ANR वाली गड़बड़ी कहां है सामान्य रूप से हो रहा है, तो बाकी के मुख्य थ्रेड स्टैक की जांच करें और देखें कि ऑपरेशन और उसे ऑप्टिमाइज़ करना या उसे ज़रूरी पाथ से बाहर कर देना.

  4. सेवाओं के बारे में ज़्यादा जानकारी के लिए, ये पेज देखें:

    कॉन्टेंट देने वाला जवाब नहीं दे रहा है

    कॉन्टेंट देने वाले को ANR की गड़बड़ी तब होती है, जब रिमोट कॉन्टेंट देने वाले को को बंद कर दिया जाता है.

    डिफ़ॉल्ट टाइम आउट अवधि: इसका इस्तेमाल करके कॉन्टेंट देने वाले की ओर से तय की गई ContentProviderClient.setDetectNotResponding. ANR की टाइम आउट की अवधि इसमें रिमोट कॉन्टेंट देने वाले की क्वेरी को चलाने में लगने वाला कुल समय शामिल होता है, जो अगर रिमोट ऐप्लिकेशन पहले से नहीं चल रहा था, तो उसे कोल्ड-स्टार्ट करना भी शामिल है.

    कॉन्टेंट देने वाले ऐप्लिकेशन से होने वाली ANR की गड़बड़ियों से बचने के लिए, यहां दिए गए सबसे सही तरीके अपनाएं:

    • पक्का करें कि ऐप्लिकेशन का स्टार्टअप तेज़ हो, क्योंकि ANR टाइम आउट में इसे गिना जाता है, अगर ऐप्लिकेशन को कॉन्टेंट देने वाले पर चलाया जाना शुरू हो गया हो.
    • पक्का करें कि कॉन्टेंट देने वाले की क्वेरी तेज़ हों.
    • एक साथ ब्लॉक करने वाले ऐसे कई बाइंडर कॉल न करें जो आपके सभी के बाइंडर थ्रेड हैं.

    सामान्य वजहें

    यहां दी गई टेबल में, कॉन्टेंट देने वाले के एएनआर और सुझाए गए एएनआर की आम वजहें बताई गई हैं समाधान.

    वजह क्या होता है सिग्नल सुझाया गया हल
    कॉन्टेंट देने वाली धीमी क्वेरी कॉन्टेंट देने वाले को कार्रवाई करने में बहुत ज़्यादा समय लगता है या उसे ब्लॉक कर दिया जाता है. android.content.ContentProvider$Transport.query फ़्रेम बाइंडर थ्रेड में है. Optimize कॉन्टेंट देने वाले की क्वेरी. पता लगाएं कि बाइंडर किस वजह से ब्लॉक हो रहा है थ्रेड.
    ऐप्लिकेशन शुरू होने की रफ़्तार कम है कॉन्टेंट देने वाले के ऐप्लिकेशन को शुरू होने में बहुत समय लगता है. ActivityThread.handleBindApplication फ़्रेम इसमें है मुख्य थ्रेड. ऐप्लिकेशन स्टार्टअप को ऑप्टिमाइज़ करें.
    बाइंडर थ्रेड खत्म हो गया है—सभी बाइंडर थ्रेड व्यस्त हैं सभी बाइंडर थ्रेड, अन्य सिंक्रोनस अनुरोध भेजने में व्यस्त हैं. कॉन्टेंट देने वाले बाइंडर कॉल नहीं चलाए जा सकते. ऐप्लिकेशन शुरू नहीं हो रहा है, सभी बाइंडर थ्रेड व्यस्त हैं, और कॉन्टेंट कंपनी नहीं चल रही है. बाइंडर थ्रेड पर लोड कम करें. इसका मतलब है कि सिंक्रोनस आउटगोइंग कम करें इनकमिंग कॉल हैंडल करते समय बाइंडर कॉल करें या कम काम करें.

    डीबग करने का तरीका

    कॉन्टेंट देने वाले की ANR की गड़बड़ी को डीबग करने के लिए, Google Play Console या Firebase Crashlytics का इस्तेमाल करें. जैसे, मुख्य थ्रेड और बाइंडर थ्रेड काम कर रहे हैं.

    इस फ़्लो चार्ट में, कॉन्टेंट देने वाले की ANR वाली गड़बड़ी को डीबग करने का तरीका बताया गया है:

    सातवीं इमेज. कॉन्टेंट देने वाले की ANR वाली गड़बड़ी को डीबग करने का तरीका.

    यह कोड स्निपेट दिखाता है कि बाइंडर थ्रेड कैसा दिखता है सामग्री देने वाले की धीमी क्वेरी के कारण अवरोधित है. इस मामले में, कॉन्टेंट देने वाले डेटाबेस को खोलते समय, क्वेरी लॉक होने का इंतज़ार करती है.

    binder:11300_2 (tid=13) Blocked
    
    Waiting for osm (0x01ab5df9) held by at com.google.common.base.Suppliers$NonSerializableMemoizingSupplier.get(Suppliers:182)
    at com.example.app.MyClass.blockingGetOpenDatabase(FooClass:171)
    [...]
    at com.example.app.MyContentProvider.query(MyContentProvider.java:915)
    at android.content.ContentProvider$Transport.query(ContentProvider.java:292)
    at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:107)
    at android.os.Binder.execTransactInternal(Binder.java:1339)
    at android.os.Binder.execTransact(Binder.java:1275)
    

    नीचे दिया गया कोड स्निपेट दिखाता है कि मुख्य थ्रेड कैसा दिखता है ऐप्लिकेशन के धीमे शुरू होने की वजह से ब्लॉक किया गया. इस मामले में, ऐप्लिकेशन का स्टार्टअप धीमा हो रहा है, डैगर शुरू करने के दौरान विवाद लॉक करना.

    main (tid=1) Blocked
    
    [...]
    at dagger.internal.DoubleCheck.get(DoubleCheck:51)
    - locked 0x0e33cd2c (a qsn)at dagger.internal.SetFactory.get(SetFactory:126)
    at com.myapp.Bar_Factory.get(Bar_Factory:38)
    [...]
    at com.example.app.MyApplication.onCreate(DocsApplication:203)
    at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1316)
    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6991)
    at android.app.ActivityThread.-$$Nest$mhandleBindApplication(unavailable:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2235)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:205)
    at android.os.Looper.loop(Looper.java:294)
    at android.app.ActivityThread.main(ActivityThread.java:8170)
    at java.lang.reflect.Method.invoke(Native method:0)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
    

    नौकरी का धीमा जवाब

    धीमे जॉब रिस्पॉन्स ANR की समस्या तब होती है, जब ऐप्लिकेशन को जवाब देने में ज़्यादा समय लगता है JobService.onStartJob() या JobService.onStopJob() या इसमें बहुत ज़्यादा समय लगता है JobService.setNotification() का इस्तेमाल करके सूचना दें. इससे पता चलता है कि ऐप्लिकेशन के मुख्य थ्रेड को कुछ और करने से ब्लॉक किया गया.

    अगर JobService.onStartJob() या JobService.onStopJob() से जुड़ी कोई समस्या है, देखें कि मुख्य थ्रेड में क्या हो रहा है. अगर समस्या JobService.setNotification(), इसे जल्द से जल्द कॉल करें. सूचना देने से पहले, बहुत सारे काम न करें.

    मिस्ट्री एएनआर

    कभी-कभी यह पता नहीं चल पाता है कि ANR की समस्या क्यों हो रही है या ज़रूरी जानकारी मौजूद नहीं है क्लस्टर सिग्नेचर और ANR रिपोर्ट में इसे डीबग करने की जानकारी. ऐसे मामलों में, अब भी कुछ तरीके हैं. इनकी मदद से, यह पता लगाया जा सकता है कि ANR वाली गड़बड़ी ठीक है या नहीं कार्रवाई करने योग्य.

    मैसेज की सूची कुछ समय से इस्तेमाल में नहीं है या localPollOne

    अगर आपको फ़्रेम में android.os.MessageQueue.nativePollOnce फ़्रेम स्टैक होता है, तो इससे अक्सर यह पता चलता है कि प्रतिक्रिया नहीं देने वाला संदिग्ध थ्रेड असल में कुछ समय से इस्तेमाल में नहीं है और लूपर मैसेज का इंतज़ार कर रहा है. Google Play Console में, ANR की जानकारी इस तरह दिखें:

    Native method - android.os.MessageQueue.nativePollOnce
    Executing service com.example.app/com.example.app.MyService
    

    उदाहरण के लिए, अगर मुख्य थ्रेड कुछ समय से इस्तेमाल में नहीं है, तो स्टैक इस तरह दिखेंगे:

    "main" tid=1 NativeMain threadIdle
    
    #00  pc 0x00000000000d8b38  /apex/com.android.runtime/lib64/bionic/libc.so (__epoll_pwait+8)
    #01  pc 0x0000000000019d88  /system/lib64/libutils.so (android::Looper::pollInner(int)+184)
    #02  pc 0x0000000000019c68  /system/lib64/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+112)
    #03  pc 0x000000000011409c  /system/lib64/libandroid_runtime.so (android::android_os_MessageQueue_nativePollOnce(_JNIEnv*, _jobject*, long, int)+44)
    at android.os.MessageQueue.nativePollOnce (Native method)
    at android.os.MessageQueue.next (MessageQueue.java:339)  at android.os.Looper.loop (Looper.java:208)
    at android.app.ActivityThread.main (ActivityThread.java:8192)
    at java.lang.reflect.Method.invoke (Native method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:626)
    at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1015)
    

    काम नहीं करने वाला संदिग्ध थ्रेड कुछ समय से इस्तेमाल में न होने की कई वजहें हो सकती हैं:

    • आखिर में स्टैक डंप. थ्रेड को रिकवर होने के कुछ समय बाद ही, ANR ट्रिगर और स्टैक डंप किए जा रहे हैं. Android पर Pixel में इंतज़ार का समय 13 का समय करीब 100 मि॰से॰ है, लेकिन यह 1 से॰ से ज़्यादा भी हो सकता है. Android 14 पर Pixel में इंतज़ार का समय यह है आम तौर पर 10 मि॰से॰ से कम होता है.
    • थ्रेड के बारे में गलत जानकारी देना. ANR सिग्नेचर बनाने के लिए इस्तेमाल किया गया थ्रेड नहीं था असल में काम न करने वाला थ्रेड जिसकी वजह से ANR की गड़बड़ी हुई. ऐसी स्थिति में, ये तरीके अपनाकर देखें देखें कि ANR की गड़बड़ी इनमें से कोई एक है या नहीं:
    • पूरे सिस्टम में समस्या. सिस्टम पर ज़्यादा लोड होने की वजह से, यह प्रोसेस शेड्यूल नहीं की जा सकी कोई समस्या है.

    कोई स्टैक फ़्रेम नहीं है

    कुछ ANR रिपोर्ट में ANR वाले स्टैक शामिल नहीं होते हैं. इसका मतलब है कि ANR रिपोर्ट जनरेट करते समय, स्टैक डंपिंग नहीं की जा सकी. कुछ स्टैक फ़्रेम न होने की ये वजहें हो सकती हैं:

    • स्टैक लेने में बहुत ज़्यादा समय लगता है और इससे ज़्यादा समय भी नहीं लगता.
    • स्टैक जोड़े जाने से पहले प्रक्रिया खत्म हो गई या खत्म हो गई.
    [...]
    
    --- CriticalEventLog ---
    capacity: 20
    timestamp_ms: 1666030897753
    window_ms: 300000
    
    libdebuggerd_client: failed to read status response from tombstoned: timeout reached?
    
    ----- Waiting Channels: pid 7068 at 2022-10-18 02:21:37.<US_SOCIAL_SECURITY_NUMBER>+0800 -----
    
    [...]
    

    स्टैक फ़्रेम के बिना ANR वाली गड़बड़ियों पर, क्लस्टर के हस्ताक्षर या एएनआर वाली कार्रवाई नहीं की जा सकती रिपोर्ट. अगर समस्या बड़ी है, तो डीबग करने के लिए, ऐप्लिकेशन के अन्य क्लस्टर देखें इतना काफ़ी होगा कि आम तौर पर इसका अपना क्लस्टर होगा जिसमें स्टैक फ़्रेम मौजूद होते हैं. दूसरा विकल्प परफ़ेटो ट्रेस देखना है.

    पहले से मालूम समस्याएं

    अपने ऐप्लिकेशन की समीक्षा पूरी करने के लिए, उसमें टाइमर लगाकर रखें ANR वाली गड़बड़ी के ट्रिगर से पहले ब्रॉडकास्ट हैंडलिंग, शायद ठीक से काम न करे. इसकी वजह यह है कि जिससे सिस्टम ANR को मॉनिटर करता है.