2013-07-07 5 views
7

मैं एक ऐप विकसित कर रहा हूं, और हर बार एक बार मेरे पृष्ठभूमि कार्यकर्ता धागे में से एक को एक प्रकार या किसी अन्य का अपवाद नहीं होगा। ये अपवाद थ्रेड को क्रैश करते हैं, लेकिन चूंकि यह UI थ्रेड पर नहीं है, इसलिए ऐप चल रहा है। मैं पूरे ऐप को क्रैश करने के लिए पृष्ठभूमि थ्रेड में इन बेजोड़ अपवादों को कैसे मजबूर कर सकता हूं? यह अच्छा होगा अगर समान प्रासंगिक क्रैश जानकारी (जैसे स्टैक ट्रेस) उपलब्ध हों।एंड्रॉइड: थ्रेड में अनकॉच अपवाद के साथ फोर्स क्रैश

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

उत्तर

0

आप java.lang.Thread.UncaughtExceptionHandler को लागू करने वाले वर्ग में अपना अपरिचित अपवाद पकड़ सकते हैं।

  • एक वर्ग है कि UncaughtExceptionHandler लागू करता है बना सकते हैं और व्यवहार आप uncaughtException overidden समारोह में चाहते डाल दिया।
    आप इस फ़ंक्शन में किसी भी व्यवहार को सर्वर पर लॉग भेजना चाहते हैं, उपयोगकर्ता को कस्टम क्रैश संवाद दिखाएं आदि
  • अपनी गतिविधि/थ्रेड में Thread.setDefaultUncaughtExceptionHandler() जोड़ें; और अपने अपवाद हैंडलर वर्ग का एक उदाहरण दें।


+0

यह सभी निष्पादक कार्यान्वयन के लिए काम नहीं करता है। उनमें से कुछ हैंडलर को फोन नहीं करते हैं। आपको 'एक्सेक्यूट के बाद' ओवरराइड करना होगा और इसे रनटाइम अपवाद या क्रैश करने के लिए मजबूर करने के लिए वहां से त्रुटि को पुनर्स्थापित करना होगा। – Monstieur

2

देर जवाब है, लेकिन मैं अपने आप को एक ही सवाल पूछ रहा था।

हम उत्पादन में क्रैशलिटिक्स का उपयोग करते हैं, लेकिन यदि ऐप विकास के लिए बनाया गया है, तो कुछ दावे सक्षम हैं, और एक त्रुटि लॉगिंग वास्तव में इसे फेंकता है, ताकि हम डेवलपर किसी भी गलत व्यवहार का पता लगा सकें।

लेकिन जैसा कि आपने टिप्पणी की, पृष्ठभूमि थ्रेड में कोई त्रुटि फेंकने से ऐप को क्रैश नहीं होता है।

यह सुनिश्चित करने के लिए कि विकास के लिए निर्माण करते समय ऐप तुरंत क्रैश हो जाए, हम मुख्य थ्रेड पर अपवाद फेंकने के लिए मुख्य लूपर पर हैंडलर का उपयोग करते हैं।

ऐसा लगता है कि इस तरह एक सा:


public static void assertTrue(boolean condition, String msg) { 
    if (condition) { 
     return; 
    } 

    final IllegalStateException e = new IllegalStateException(message); 
    if (BuildConfig.RELEASE) { 
     Crashlytics.logException(e); 
     return; 
    } 

    Log.e("ASSERT", message, e); 
    if (Looper.getMainLooper() != Looper.myLooper()) { 
     mMainThreadHandler.post(new Runnable() { 
      @Override 
      public void run() { 
       throw e; 
      } 
     }); 
    } 

    throw e; 
} 
+0

हालांकि यह एक आशाजनक समाधान की तरह दिखता है, कुछ चीजें मेरे लिए अस्पष्ट नहीं हैं: 1. रन में ("अपूर्ण अपवाद" के लिए इंटेलिज त्रुटियों से कैसे बचें?) 2. इस स्थिर संदर्भ में आपको मुख्य थ्रेडहैंडलर कहां मिलता है? –

0

नीचे

असल में मूल संस्करण, आगे की जांच के बाद पाया है कि आप बस अपने मुख्य थ्रेड पर अपवाद सौंपने के द्वारा अपने कोड को आसान बनाने में कर सकते हैं सीधे।

public static <T extends Exception> void throwOnMainThread(T exception) { 
    Thread mainThread = Looper.getMainLooper().getThread(); 
    mainThread.getUncaughtExceptionHandler().uncaughtException(mainThread, exception); 
} 

यह कहीं से भी मुख्य थ्रेड दुर्घटना और एक कस्टम UncaughtExceptionHandler की स्थापना के बिना भी कॉल करने के लिए सुरक्षित है होगा।

मूल जवाब:

public static <T extends Exception> void throwOnMainThread(final T exception) { 
    Handler mainThreadHandler = new Handler(Looper.getMainLooper()); 
    mainThreadHandler.post(new Runnable() { 
     @Override 
     public void run() { 
      Thread currentThread = Thread.currentThread(); 
      currentThread.getUncaughtExceptionHandler().uncaughtException(currentThread, exception); 
     } 
    }); 
} 

पहले हम मुख्य Looper के माध्यम से मुख्य थ्रेड के लिए एक हैंडलर मिलती है:

एक पृष्ठभूमि धागे से मुख्य थ्रेड दुर्घटनाग्रस्त निम्नलिखित स्थिर विधि पर विचार करें।फिर हम एक रननेबल पोस्ट करते हैं जो उस थ्रेड के UncaughtExceptionHandler का आह्वान करेगा और इसे हमारे अपवाद को सौंप देगा।

इसे एक यूटिल क्लास में रखें और आप मूल रूप से कहीं भी मुख्य धागे पर अपवाद फेंकने में सक्षम होंगे।

मुख्य थ्रेड क्रैशिंग तो उदाहरण के लिए

ThreadUtils.throwOnMainThread(new RuntimeException()); 

उपयोग करके प्राप्त किया जा सकता है।

संबंधित मुद्दे