6

我問this問題一段時間回來Stackoverflow,答案工作對我來說,它覆蓋handleUncaughtException,我保存了異常,並拋出默認Unfortunately app has stopped working,但是當我在我的應用程序集成了這個,我面臨一個問題。如何覆蓋handleUncaughtException不改變其functionallity

這是我得到的答案。

private Thread.UncaughtExceptionHandler defaultExceptionHandler; 

    public void registerCrash(){ 
     defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); 

     Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler(){ 
      @Override 
      public void uncaughtException (Thread thread, Throwable e){ 
       handleUncaughtException (thread, e); 
       if(defaultExceptionHandler != null){ 
        defaultExceptionHandler.uncaughtException(thread, e); 
       } 
      } 
     }); 
    } 

它做什麼,它先於handleUncaughtException (thread, e);我保存的崩潰日誌在這種方法中,然後將其讀入這一行

if(defaultExceptionHandler != null){ 
    defaultExceptionHandler.uncaughtException(thread, e); 
} 

在這裏,我們再次拋出未捕獲的異常,所以它進入第一再次行,並再次保存異常,並進入循環,應用程序不響應。

我想要的是保存崩潰日誌,然後向用戶顯示默認Unfortunate消息。

編輯

在應用程序啓動它讀取這一點;

defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); 

當應用程序崩潰時,它讀取這些行

Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler(){ 
    @Override 
    public void uncaughtException (Thread thread, Throwable e){ 

     handleUncaughtException (thread, e); //Custom Method 

     if(defaultExceptionHandler != null){ 
      defaultExceptionHandler.uncaughtException(thread, e); 
     } 
    } 

所以它首先進入handleUncaughtException()在那裏,我已經提供了自定義的實現,然後它去這一點;

if(defaultExceptionHandler != null){ 
    defaultExceptionHandler.uncaughtException(thread, e); 
} 

defaultExceptionHandler從不爲空;所以它會在多次崩潰的情況下循環。

我曾嘗試在其中添加count,但每次都是0

+0

'所以它會在一個循環中多的情況下,崩潰'你能指出這種情況發生嗎?什麼導致了另一個異常發生? – azizbekian

+0

@azizbekian:我無法找到reporduce它的步驟。這不會每次都發生,但有時 – Kirmani88

+0

什麼是defaultExceptionHandler方法。這是你自己的方法嗎?如果是,則發佈該方法代碼。併發布handleUncaughtException(線程,e)方法代碼 –

回答

1

最可能的解釋是您的registerCrash()方法被調用兩次。

您第一次註冊Handler 1;此時沒有默認處理程序,因此它將defaultExceptionHandler設置爲null。第二次,您註冊Handler 2,然後更新defaultExceptionHandler指向Handler 1

對於未捕獲的異常,Handler 2首先被調用。它會調用您的自定義處理程序方法,然後調用defaultExceptionHandler,它現在指向Handler 1

Handler 1被調用。它會再次調用您的自定義處理程序方法,然後調用defaultExceptionHandler,,它現在指向自己。這一步重複,直到你的堆棧溢出。

我建議兩個更改。首先,添加一個警衛以確保您只註冊一次您的應急處理程序。其次,不要將後備處理程序存儲在一個字段中;將它捕獲到一個閉包中,這樣處理程序看到的值永遠不會改變。

private static final AtomicBoolean CRASH_HANDLER_REGISTERED = new AtomicBoolean(); 

public void registerCrash() { 
    if (CRASH_HANDLER_REGISTERED.compareAndSet(false, true)) { 
     final Thread.UncaughtExceptionHandler defaultHandler = 
      Thread.getDefaultUncaughtExceptionHandler(); 

     Thread.setDefaultUncaughtExceptionHandler(
      new Thread.UncaughtExceptionHandler() { 
       @Override 
       public void uncaughtException(Thread thread, Throwable e) { 
        handleUncaughtException(thread, e); // Custom Method 

        if (defaultHandler != null) { 
         defaultHandler.uncaughtException(thread, e); 
        } 
       } 
      } 
     ); 
    } 
} 
0

我建議你去嘗試另一種方法,避免覆蓋例外,捕獲它和retrive的錯誤代碼,這樣做:

when x code with x conditions verify, do that