दिलचस्प पोस्ट
मल्टी-आयामी वेक्टर अनुमति अस्वीकृति: इसमें एंड्रॉइड पिरमिशन की आवश्यकता है। INTERACT_ACROSS_USERS_FULL फायरबेज एंड्रॉइड: उपयोगकर्ता नाम अद्वितीय बनाएं आर में एक चर का सटीक मान प्रदर्शित करें बूटस्ट्रैप में 7 समान कॉलम जावा में एक निश्चित आकार की सूची को परिभाषित करें MongoDB फील्ड ऑर्डर और अपडेट के बाद दस्तावेज़ स्थिति परिवर्तन जावा कोर डंप से जानकारी का विश्लेषण कैसे करें? मूल्य को एक रूप से दूसरे में पास करें एंड्रॉइड में जीमेल से उपयोगकर्ता के प्रवेश के बाद टोकन का उपयोग कैसे किया जाए? नेस्टेड जेएसओएन डेटा तक कैसे पहुंचें आईफ़ोन: मैकिकिट पर दो बिंदुओं के बीच की रेखा कैसे खींचना है? एंड्रॉइड। Support.v7.widget.CardView का उपयोग करके मेरी प्रोजेक्ट (एक्लिप्स) वसा जार क्या है? नए स्काला प्रतिबिंब एपीआई के साथ साथी वस्तु उदाहरण प्राप्त करें

एंड्रॉइड में वैश्विक असंतुलित अपवाद हैंडलर सेट करने का आदर्श तरीका

मैं अपने एंड्रॉइड एप्लिकेशन के सभी थ्रेड्स के लिए एक वैश्विक अनकक्षित अपवाद हैंडलर सेट करना चाहता हूं। इसलिए, मेरे Application उप- Thread.UncaughtExceptionHandler में Thread.UncaughtExceptionHandler कार्यान्वयन को निर्धारित किया है। Thread.UncaughtExceptionHandler बिना अपवादों के लिए डिफ़ॉल्ट हैंडलर के रूप में।

 Thread.setDefaultUncaughtExceptionHandler( new DefaultExceptionHandler(this)); 

मेरे कार्यान्वयन में, मैं एक अपवाद संदेश प्रदर्शित करने के लिए एक AlertDialog प्रदर्शित करने के लिए कोशिश कर रहा हूँ।

हालांकि, यह काम करने के लिए नहीं लगता है जब भी, किसी भी थ्रेड के लिए कोई अपवाद फेंक दिया जाता है जो अप्रबंधित होता है, मुझे स्टॉक मिलता है, ओएस-डिफ़ॉल्ट संवाद ("क्षमा करें! -अनुप्रयोग-रोक-अप्रत्याशित रूप से संवाद")।

अपमानित अपवादों के लिए डिफ़ॉल्ट हैंडलर सेट करने का सही और आदर्श तरीका क्या है?

वेब के समाधान से एकत्रित समाधान "एंड्रॉइड में वैश्विक असंतुलित अपवाद हैंडलर सेट करने का आदर्श तरीका"

आपको ये करना चाहिए था (सुनिश्चित करें कि आप प्रक्रिया को बाद में रोकने का कारण बनें – चीज़ें अनिश्चित स्थिति में हो सकती हैं।)

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

अपने हैंडलर के शीर्ष पर कुछ लॉग संदेश जोड़ें, यह देखने के लिए कि क्या यह वहां हो रहा है GetDefaultUncaughtExceptionHandler से परिणाम प्रिंट करें और फिर क्रैश होने के कारण एक अपवाद अपवाद फेंकें। क्या हो रहा है यह देखने के लिए लॉककट आउटपुट पर नज़र रखें।

मैंने एंड्रॉइड के कस्टम हैंडलिंग के लिए एक सरल समाधान पोस्ट किया है, जो पहले बहुत समय पहले क्रैश करता था। यह थोड़ा हैक हालांकि यह सभी एंड्रॉइड वर्ज़न (लॉलीपॉप सहित) पर काम करता है।

सबसे पहले सिद्धांत का एक छोटा सा जब आप एंड्रॉइड में अनकही अपवाद हैंडल का उपयोग करते हैं, तो प्रमुख मुद्दे मुख्य (उर्फ यूआई) थ्रेड में फेंक दिए गए अपवादों के साथ आते हैं। और यहाँ क्यों है जब ऐप ऐप शुरू होता है तो ActivityThread.main विधि कॉल करता है जो आपके एप के मुख्य लूप को तैयार और शुरू करता है:

 public static void main(String[] args) { … … Looper.prepareMainLooper(); … Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); } 

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

प्रस्तावित समाधान काफी आसान है। हम अपने द्वारा Looper.loop विधि चलाते हैं और इसे प्रयास-पकड़ ब्लॉक के साथ घेरते हैं। जब कोई अपवाद पकड़ा जाता है तो हम इसे हम चाहते हैं (उदाहरण के लिए हमारी कस्टम रिपोर्ट गतिविधि शुरू करें) और फिर Looper.loop विधि को कॉल करें।

निम्नलिखित पद्धति इस तकनीक को दर्शाती है (इसे Application.onCreate सुनाई जानी चाहिए। अनुबंधित श्रोता):

 private void startCatcher() { UncaughtExceptionHandler systemUncaughtHandler = Thread.getDefaultUncaughtExceptionHandler(); // the following handler is used to catch exceptions thrown in background threads Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler(new Handler())); while (true) { try { Looper.loop(); Thread.setDefaultUncaughtExceptionHandler(systemUncaughtHandler); throw new RuntimeException("Main thread loop unexpectedly exited"); } catch (Throwable e) { showCrashDisplayActivity(e); } } } 

जैसा कि आप देख सकते हैं कि अपवाद अपवाद हैंडलर केवल पृष्ठभूमि धागे में दिए गए अपवादों के लिए उपयोग किया जाता है। निम्न हैंडलर उन अपवादों को पकड़ता है और उन्हें UI थ्रेड पर प्रसारित करता है:

 static class UncaughtHandler implements UncaughtExceptionHandler { private final Handler mHandler; UncaughtHandler(Handler handler) { mHandler = handler; } public void uncaughtException(Thread thread, final Throwable e) { mHandler.post(new Runnable() { public void run() { throw new BackgroundException(e); } }); } } 

इस तकनीक का उपयोग करने वाला एक उदाहरण प्रोजेक्ट मेरे गीथहब रेपो पर उपलब्ध है: https://github.com/idolon-github/android-crash-catcher

एफडब्ल्यूआईडब्ल्यू मुझे पता है कि यह थोड़ी दूर है, लेकिन हम सफलता के साथ Crittercism की मुफ्त योजना का उपयोग कर रहे हैं। वे कुछ प्रीमियम विशेषताओं की पेशकश भी करते हैं, जैसे अपवाद को संभालने के लिए ताकि एप्लिकेशन क्रैश न हो।

मुफ्त संस्करण में, उपयोगकर्ता अब भी क्रैश देखता है, लेकिन कम से कम मुझे ईमेल और स्टैक ट्रेस मिल रहा है।

हम भी आईओएस संस्करण का उपयोग करते हैं (लेकिन मैंने अपने सहयोगियों से सुना है कि यह काफी अच्छा नहीं है)।


यहां समान प्रश्न हैं:

  • ग्लोबल असंस अपवाद हैंडलर -> ईमेल मुझे लॉग इन करें?
  • क्या एंड्रॉइड में कुछ प्रकार के वैश्विक अपवाद हैंडल बनाना संभव है?

मुझे लगता है कि अक्षम करने के लिए अपने uncaughtException () विधि में पिछलाहैंडलर नहीं बुलाओ। अपवाद () जहां previousHandler द्वारा सेट है

 previousHandler = Thread.getDefaultUncaughtExceptionHandler(); 

यह तब तक काम नहीं करता जब तक आप कॉल नहीं करते

 android.os.Process.killProcess(android.os.Process.myPid()); 

अपने अनक्यूट एक्सपैशनहैंडलर के बहुत अंत में