2016-12-01 101 views
1

我對此有疑問,例如,在一個Java類的主要方法,下面我有一些代碼:在另一個線程中拋出的異常會使主線程崩潰嗎?

public static void main(String[] args) { 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       throw new IllegalStateException("sss"); 
      } 
     }).start(); 


     try { 
      Thread.sleep(2000); 
     } catch (Exception e) { 

     } 

     System.out.println("xxx"); 

    } 

這IllegalStateException異常不會停止執行的主要方法,我可以看到我打印「 XXX」。

但是,在Android開發中,如果我在Activity的oncreate()方法中做同樣的事情,它會使應用程序崩潰。

我想知道Android如何處理這個問題,以及它爲什麼會崩潰應用程序。

感謝

logcat的日誌:

致命異常:螺紋248

             Process: com.abc.android, PID: 3673 
                 java.lang.IllegalStateException: sss 
                  at com.abc.android.MainActivity$1.run(MainActivity.java:80) 
                  at java.lang.Thread.run(Thread.java:818) 
+0

你可以發佈你的Activity的oncreate()代碼嗎? – sasikumar

+0

線程t =新主題(新的Runnable(){ \t \t \t @Override \t \t \t公共無效的run(){ \t \t \t \t擲新IllegalStateException異常( 「SSS」); \t \t \t} \t \t }); \t \t t.start(); – Qing

+0

你把佈局代碼? – sasikumar

回答

2

每個線程都有一個選項來設置未捕獲的處理程序當線程遇到異常將被稱爲

fron Android的文檔覆蓋here

無效是,setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler EH): 設置的默認處理,由於未捕獲到異常時調用線程而突然終止,並且沒有其他處理程序已爲該線程定義。

未捕獲的異常處理首先由線程控制,然後由線程的ThreadGroup對象控制,最後由默認的未捕獲異常處理程序控制。如果線程沒有顯式的未捕獲異常處理程序集,並且線程的線程組(包括父線程組)未專門化其uncaughtException方法,則會調用默認處理程序的uncaughtException方法。

通過設置默認的未捕獲異常處理程序,應用程序可以更改處理未捕獲的異常的方式(例如記錄到特定設備或文件),這些線程已經接受系統的任何「默認」行爲提供。

請注意,默認的未捕獲異常處理程序通常不應該遵循該線程的ThreadGroup對象,因爲這可能會導致無限遞歸。

另請注意,setDefaultUncaughtExceptionHandler是一種靜態方法,這意味着它將應用於應用程序創建的所有線程。

現在,如果深入挖掘,您會發現Android Framework爲RuntimeInit.java中的所有線程定義了一個默認的未捕獲異常處理程序,它繼續報告崩潰並終止進程。

/** 
* Use this to log a message when a thread exits due to an uncaught 
* exception. The framework catches these for the main threads, so 
* this should only matter for threads created by applications. 
*/ 
private static class UncaughtHandler implements Thread.UncaughtExceptionHandler { 
    public void uncaughtException(Thread t, Throwable e) { 
     try { 
      // Don't re-enter -- avoid infinite loops if crash-reporting crashes. 
      if (mCrashing) return; 
      mCrashing = true; 
      if (mApplicationObject == null) { 
       Slog.e(TAG, "*** FATAL EXCEPTION IN SYSTEM PROCESS: " + t.getName(), e); 
      } else { 
       Slog.e(TAG, "FATAL EXCEPTION: " + t.getName(), e); 
      } 
      // Bring up crash dialog, wait for it to be dismissed 
      ActivityManagerNative.getDefault().handleApplicationCrash(
        mApplicationObject, new ApplicationErrorReport.CrashInfo(e)); 
     } catch (Throwable t2) { 
      try { 
       Slog.e(TAG, "Error reporting crash", t2); 
      } catch (Throwable t3) { 
       // Even Slog.e() fails! Oh well. 
      } 
     } finally { 
      // Try everything to make sure this process goes away. 
      Process.killProcess(Process.myPid()); 
      System.exit(10); 
     } 
    } 
} 
private static final void commonInit() { 
    if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!"); 
    /* set default handler; this applies to all threads in the VM */ 
    Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler()); 

請記住,您可以通過調用,該線程的setUncaughtExceptionHandler替代特定線程未捕獲的異常處理程序。如果你在上面的例子中這樣做,你會注意到應用程序不再崩潰。

+0

這正是我所需要的! – Qing