दिलचस्प पोस्ट
मैं अपने पर्ल स्क्रिप्ट को विंडोज़ पर सामान्य कार्यक्रमों की तरह कैसे कर सकता हूं? पायथन स्क्रिप्ट को समाप्त करना विशिष्ट फ़ोल्डर में आप एक गीट भंडार कैसे क्लोन करते हैं? AJAX और jQuery के साथ एचटीएमएल 5 फ़ाइल अपलोड का उपयोग करना MVC में $ _POST डेटा को संभालने का सही तरीका क्या है? आप जंग में एक सुरक्षित स्थिर सिंगलटन कैसे बना सकते हैं? सी # वर्तनी जांच वर्ग का उपयोग करने की कोशिश कर रहा है क्या मतलब है? जावा में एक regex के मैचों की संख्या की गणना डेटाफ़्रेम में एक समूहिंग चर के आधार पर लगातार इंडेक्स कैसे बनाएं जावा: जांचें कि कमांड लाइन तर्क शून्य हैं उड़ी से बिटमैप कैसे प्राप्त करें? X86_64 va_list संरचना का प्रारूप क्या है? मैं किसी तत्व को एक वर्ग कैसे जोड़ूं? मैं स्ट्रिंग क्यों नहीं कर सकता?

एंड्रॉइड – मैं एक एएनआर की जांच कैसे करूं?

क्या पता लगाने का एक तरीका है कि मेरे ऐप ने एएनआर (एप्लिकेशन जवाब न दे) को फेंक दिया था। मैं traces.txt फाइल में एक डेटा / डेटा पर एक नज़र लिया और मैं अपने आवेदन के लिए एक ट्रेस देखता हूँ। यह वह है जिसे मैं ट्रेस में देखता हूं।

DALVIK THREADS: "main" prio=5 tid=3 TIMED_WAIT | group="main" sCount=1 dsCount=0 s=0 obj=0x400143a8 | sysTid=691 nice=0 sched=0/0 handle=-1091117924 at java.lang.Object.wait(Native Method) - waiting on <0x1cd570> (a android.os.MessageQueue) at java.lang.Object.wait(Object.java:195) at android.os.MessageQueue.next(MessageQueue.java:144) at android.os.Looper.loop(Looper.java:110) at android.app.ActivityThread.main(ActivityThread.java:3742) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:497) at dalvik.system.NativeStart.main(Native Method) "Binder Thread #3" prio=5 tid=15 NATIVE | group="main" sCount=1 dsCount=0 s=0 obj=0x434e7758 | sysTid=734 nice=0 sched=0/0 handle=1733632 at dalvik.system.NativeStart.run(Native Method) "Binder Thread #2" prio=5 tid=13 NATIVE | group="main" sCount=1 dsCount=0 s=0 obj=0x433af808 | sysTid=696 nice=0 sched=0/0 handle=1369840 at dalvik.system.NativeStart.run(Native Method) "Binder Thread #1" prio=5 tid=11 NATIVE | group="main" sCount=1 dsCount=0 s=0 obj=0x433aca10 | sysTid=695 nice=0 sched=0/0 handle=1367448 at dalvik.system.NativeStart.run(Native Method) "JDWP" daemon prio=5 tid=9 VMWAIT | group="system" sCount=1 dsCount=0 s=0 obj=0x433ac2a0 | sysTid=694 nice=0 sched=0/0 handle=1367136 at dalvik.system.NativeStart.run(Native Method) "Signal Catcher" daemon prio=5 tid=7 RUNNABLE | group="system" sCount=0 dsCount=0 s=0 obj=0x433ac1e8 | sysTid=693 nice=0 sched=0/0 handle=1366712 at dalvik.system.NativeStart.run(Native Method) "HeapWorker" daemon prio=5 tid=5 VMWAIT | group="system" sCount=1 dsCount=0 s=0 obj=0x4253ef88 | sysTid=692 nice=0 sched=0/0 handle=1366472 at dalvik.system.NativeStart.run(Native Method) ----- end 691 ----- 

मैं यह कैसे पता लगा सकता हूं कि समस्या कहाँ है? ट्रेस में तरीके सभी एसडीके तरीके हैं

धन्यवाद।

वेब के समाधान से एकत्रित समाधान "एंड्रॉइड – मैं एक एएनआर की जांच कैसे करूं?"

एएनआर तब होता है जब "मुख्य" थ्रेड में कुछ लंबे आपरेशन होता है। यह इवेंट लूप धागा है, और यदि यह व्यस्त है, तो एंड्रॉइड एप्लिकेशन में किसी और जीयूआई ईवेंट की प्रक्रिया नहीं कर सकता है, और इस तरह एएनआर संवाद को फेंक सकता है

अब, आपके द्वारा पोस्ट किए गए ट्रेस में, मुख्य थ्रेड ठीक लग रहा है, कोई समस्या नहीं है यह MessageQueue में सुराख है, एक और संदेश आने के लिए इंतजार कर रहा है। आपके मामले में एएनआर थोड़ी देर के ऑपरेशन की संभावना थी, जो कि धागे को स्थायी रूप से अवरुद्ध करने की बजाय, ऑपरेशन समाप्त होने के बाद घटना थैली बरामद हो गई और आपका ट्रेस एएनआर के बाद

जहां ANR होने का पता लगाया जा रहा है, यह एक स्थायी ब्लॉक (उदाहरण के लिए कुछ लॉक प्राप्त करते हुए), लेकिन अगर यह केवल अस्थायी देरी है, तो यह आसान है। सबसे पहले, अपने कोड पर जाएं और vunerable स्पॉट और लंबे चलने वाले आपरेशनों के लिए देखें। घटना थ्रेड के भीतर से सॉकेट्स, लॉक, थ्रेड स्लीप्स और अन्य अवरुद्ध ऑपरेशन के उपयोग में शामिल हो सकते हैं। आपको यह सुनिश्चित करना चाहिए कि ये सभी अलग थ्रेड में होते हैं यदि कुछ भी समस्या नहीं है, तो डीडीएमएस का उपयोग करें और थ्रेड व्यू को सक्षम करें। यह आपके आवेदन में सभी थ्रेड्स को दिखाता है जैसा आपके पास है। ANR को पुन: उत्पन्न करें, और एक ही समय में मुख्य थ्रेड को रीफ़्रेश करें। इससे आपको एएनआर के समय में ठीक से दिखना चाहिए

आप एपीआई स्तर 9 और इसके बाद के संस्करण में स्ट्रिक्टोड को सक्षम कर सकते हैं।

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

 public void onCreate() { StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectAll() .penaltyLog() .penaltyDeath() .build()); super.onCreate(); } 

penaltyLog() उपयोग करते हुए आप अपने आवेदन का उपयोग करते हुए उल्लंघन के देखने के लिए एडीबी penaltyLog() के आउटपुट को देख सकते हैं।

आप सोच रहे हैं कि किस कार्य में यूआई थ्रेड है I ट्रेस फ़ाइल आपको कार्य खोजने का संकेत देती है। आपको प्रत्येक थ्रेड की स्थिति की जांच करने की ज़रूरत है

थ्रेड का राज्य

  • चलाना – एप्लिकेशन कोड निष्पादित करना
  • नींद – बुलाया Thread.sleep ()
  • मॉनिटर – एक मॉनिटर लॉक प्राप्त करने के लिए इंतजार कर रहा है
  • प्रतीक्षा करें – ऑब्जेक्ट में। वाट ()
  • देशी – मूल कोड निष्पादित करना
  • vmwait – एक वीएम संसाधन पर प्रतीक्षा कर रहा है
  • ज़ोंबी – धागा मरने की प्रक्रिया में है
  • init – थ्रेड आरंभ हो रहा है (आपको इसे नहीं देखना चाहिए)
  • शुरू – धागा शुरू करने वाला है (आपको इसे या तो नहीं देखना चाहिए)

निश्चिंत, मॉनिटर राज्य पर फोकस मॉनिटर स्टेट इंगित करता है कि थ्रेड की जांच की जाती है और थ्रेड की निलंबित स्थिति शायद डेडलॉक के लिए मुख्य कारण है।

बेसिक जांच कदम

  1. "लॉक करने का इंतज़ार" ढूंढें
    • आप मॉनिटर स्टेट "बाइंडर थ्रेड # 15" प्रीओ = 5 टीआईड = 75 मॉनिटर पा सकते हैं
    • आप भाग्यशाली हैं यदि "प्रतीक्षा करने के लिए"
    • उदाहरण: धागा = 74 द्वारा आयोजित <0blblblbl>> (एक com.foo.A) लॉक करने के लिए इंतजार कर रहा है
  2. आप देख सकते हैं कि "tid = 74" अब एक कार्य रखता है। तो tid = 74 पर जाएं
  3. tid = 74 शायद निलंबित राज्य! मुख्य कारण मिल!

ट्रेस हमेशा "लॉक करने के लिए प्रतीक्षा" नहीं होता है इस मामले में मुख्य कारण ढूंढना कठिन है।

मैं पिछले कुछ महीनों के लिए एंड्रॉइड सीख रहा हूं, इसलिए मैं एक विशेषज्ञ से बहुत दूर हूं, लेकिन वास्तव में ANRs पर दस्तावेज से मुझे निराश किया गया है।

ज्यादातर सलाह उनको टालने या उन्हें फिक्सिंग करने के लिए तैयार रहती हैं, जो आपके कोड को देखकर आंखों से करता है, जो महान है, लेकिन मुझे पता लगाने के लिए कुछ भी नहीं मिला।

तीन चीजें हैं जो आपको वास्तव में एएनआर लॉग के साथ देखने की जरूरत हैं

1) डेडलॉक: जब कोई थ्रेड डब्लूआईटी स्थिति में होता है, तो आप यह पता लगाने के लिए कि कौन "आयोजित किया गया है =" का विवरण देख सकता है ज्यादातर समय, यह स्वयं के द्वारा आयोजित किया जाएगा, लेकिन अगर यह किसी दूसरे धागे द्वारा आयोजित किया जाता है, तो यह एक खतरे का संकेत होने की संभावना है उस धागे को देखो और देखें कि यह किसके द्वारा आयोजित किया गया है। आपको एक पाश मिल सकता है, जो एक स्पष्ट संकेत है कि कुछ गलत हो गया है। यह बहुत दुर्लभ है, लेकिन यह पहला मुद्दा है क्योंकि ऐसा होता है, यह एक दुःस्वप्न है

2) मुख्य धागा प्रतीक्षा: यदि आपका मुख्य धागा डब्लूआईटी स्थिति में है, तो जांचें कि क्या इसे किसी अन्य धागे द्वारा आयोजित किया गया है। ऐसा नहीं होना चाहिए, क्योंकि आपके UI थ्रेड को पृष्ठभूमि थ्रेड द्वारा नहीं रखना चाहिए।

इन परिदृश्यों के दोनों, मतलब है कि आपको अपने कोड को महत्वपूर्ण रूप से पुन: उपयोग करने की आवश्यकता है

3) मुख्य धागा पर भारी संचालन: यह एएनआर का सबसे आम कारण है, लेकिन कभी-कभी मुश्किलों में से एक को खोजने और तय करना मुख्य थ्रेड विवरण देखें। स्टैक ट्रेस को स्क्रॉल करें और जब तक आप उन वर्गों को नहीं देखते हैं जिन्हें आप पहचानते हैं (अपने ऐप से)। ट्रेस में तरीकों को देखो और पता लगाएं कि क्या आप इन जगहों पर नेटवर्क कॉल, डीबी कॉल्स आदि बना रहे हैं।

अंत में, और मैं अपने स्वयं के कोड को बेतरती ढंग से प्लग करने के लिए माफी मांगता हूं, आप https://github.com/HarshEvilGeek/Android-Log-Analyzer पर लिखा गया अजगर लॉग विश्लेषक का उपयोग कर सकते हैं यह आपके लॉग फाइलों के माध्यम से, एएनआर फाइलें खोलें, खोजें डेडलॉक, मुख्य थ्रेड्स की प्रतीक्षा करना, अपने एजेंट लॉग में बिना अपवाद अपवादों को ढूंढें और स्क्रीन पर ये सभी को प्रिंट तरीके से पढ़ने के लिए अपेक्षाकृत आसानी से प्रिंट करें। इसका उपयोग करने के तरीके के बारे में जानने के लिए ReadMe फ़ाइल (जो मैं जोड़ना है) पढ़ें। पिछले हफ्ते में मुझे एक टन की मदद मिली है!

जब भी आप समय के मुद्दों का विश्लेषण कर रहे हैं, तो डीबगिंग अक्सर मदद नहीं करता है, क्योंकि ब्रेकपॉइंट पर एप को ठंड के रूप में समस्या दूर हो जाएगी।

आपका सर्वश्रेष्ठ शर्त ऐप के विभिन्न धागे और कॉलबैक में लॉगिंग कॉल (लॉग। XXX ()) को सम्मिलित करना है और देखें कि विलंब कब है। यदि आपको एक स्टैकट्र्रेस की आवश्यकता है, तो एक नया अपवाद बनाएं (बस एक को तत्काल) और लॉग इन करें

एएनआर क्या ट्रिगर्स?

आम तौर पर, सिस्टम ANR प्रदर्शित करता है यदि कोई उपयोगकर्ता उपयोगकर्ता इनपुट का जवाब नहीं दे सकता है

किसी भी स्थिति में, जहां आपका ऐप एक संभावित रूप से लंबा ऑपरेशन करता है, आपको UI थ्रेड पर काम नहीं करना चाहिए, लेकिन इसके बजाय एक कार्यकर्ता थ्रेड बनाएं और वहां के अधिकांश काम करें। यह यूआई थ्रेड (जो उपयोगकर्ता इंटरफ़ेस इवेंट लूप को चलाता है) चल रहा है और सिस्टम को अपने कोड के जमे हुए होने से पूरा करने से रोकता है

एएनआर से कैसे बचें

एंड्रॉइड अनुप्रयोग सामान्य रूप से "UI थ्रेड" या "मुख्य थ्रेड" डिफ़ॉल्ट रूप से एक धागे पर पूरी तरह से चलते हैं)। इसका मतलब यह है कि आपका आवेदन जो कुछ यूआई थ्रेड में कर रहा है, जो पूरा करने में लंबा समय लगता है ANR संवाद को ट्रिगर कर सकता है क्योंकि आपका एप्लिकेशन इनपुट इवेंट या इरादे के प्रसारण को संभालने का मौका नहीं देता है

इसलिए, UI थ्रेड में चलने वाली किसी भी विधि को उस थ्रेड पर जितना संभव हो उतना छोटा कार्य करना चाहिए। विशेष रूप से, क्रियाकलापों को महत्वपूर्ण जीवन-चक्र विधियों जैसे onCreate () और onResume () में स्थापित करने के लिए जितना संभव हो उतना करना चाहिए। नेटवर्क या डेटाबेस संचालन जैसे संभावित लंबे समय से चलने वाला संचालन, या कंप्यूटेशनलली महंगी गणना जैसे बिटमैप को कार्यकर्ता धागे (या डेटाबेस के संचालन के मामले में, एक अतुल्यकालिक अनुरोध के माध्यम से) किया जाना चाहिए।

कोड: AsyncTask क्लास के साथ कार्यकर्ता थ्रेड

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { // Do the long-running work in here protected Long doInBackground(URL... urls) { int count = urls.length; long totalSize = 0; for (int i = 0; i < count; i++) { totalSize += Downloader.downloadFile(urls[i]); publishProgress((int) ((i / (float) count) * 100)); // Escape early if cancel() is called if (isCancelled()) break; } return totalSize; } // This is called each time you call publishProgress() protected void onProgressUpdate(Integer... progress) { setProgressPercent(progress[0]); } // This is called when doInBackground() is finished protected void onPostExecute(Long result) { showNotification("Downloaded " + result + " bytes"); } } 

कोड: कार्यकर्ता धागा निष्पादित करें

इस कार्यकर्ता थ्रेड को निष्पादित करने के लिए, बस एक उदाहरण बनाएं और कॉल निष्पादित करें ():

 new DownloadFilesTask().execute(url1, url2, url3); 

स्रोत

http://developer.android.com/training/articles/perf-anr.html

एएनआर के साथ मेरी समस्या, बहुत काम के बाद मुझे पता चला कि एक धागा उस संसाधन को बुला रहा था जो लेआउट में मौजूद नहीं था, एक अपवाद वापस करने के बजाय, मुझे एएनआर मिला …

आपको /data/anr/traces.txt फ़ाइल में "लॉक करने का इंतज़ार" देखने की आवश्यकता है

यहां छवि विवरण दर्ज करें

अधिक विवरण के लिए: एंड्रॉइड और प्ले से टूल के साथ उच्च प्रदर्शन के लिए इंजीनियर (Google I / O '17)

@ हौरीन ली के बेसिक पर उत्तर, मैंने traces.txt से ANR की जांच करने में मदद करने के लिए एक छोटी अजगर स्क्रिप्ट traces.txt

grapvhviz ग्राफिक्स के रूप में ग्राफिक्स के रूप में आउटपुट होगा यदि आपने अपने सिस्टम पर grapvhviz स्थापित किया है।

 $ ./anr.py --format png ./traces.txt 

एक पीएनजी नीचे की तरह आउटपुट होगा यदि फ़ाइल traces.txt में ANR का पता लगाया गया है। यह अधिक सहज है

यहां छवि विवरण दर्ज करें

ऊपर दिए गए नमूना traces.txt फ़ाइल यहां से प्राप्त हुई थी।

एएनआर-वॉचडॉग लायब्रेरी का उपयोग एएनआर स्टैक ट्रेसेस को सही ढंग से ट्रैक और कैप्चर करने के बारे में विचार करें। आप उन्हें अपने क्रैश रिपोर्टिंग लायब्रेरी में भेज सकते हैं। मैं इस परिदृश्य में setReportMainThreadOnly() का उपयोग करने की सलाह देता हूं ध्यान दें कि एएनआर आपके Google Play डेवलपर कंसोल को भेजी गई रिपोर्ट प्रायः सटीक समस्या को हल करने के लिए पर्याप्त सटीक नहीं है।

आप या तो ऐप फ्रिज पॉइंट के एक चेक एक्सपेरियन फेंक सकते हैं, या एएनआर के होने से ऐप बल को बंद कर सकते हैं।