2016-12-01 3 views
1

私はこれに疑問を持っているが、例えば、Javaクラスのmainメソッドでは、私は以下のいくつかのコードがあります:「別のスレッドでスローされた例外は、メインスレッドをクラッシュさせますか?

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が実行からmainメソッドを止めるつもりはない、と私は私が印刷見ることができます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

アクティビティのoncreate()コードを投稿できますか? – sasikumar

+0

スレッドt =新しいスレッド(新しいRunnableを(){ \t \t \t @Override \t \t \t公共ボイドラン(){ \t \t \t \t投新しいIllegalStateExceptionが( "SSS"); \t \t \t} \t \t }); \t \t t.start(); – Qing

+0

レイアウトコードを入れましたか? – sasikumar

答えて

2

すべてのスレッドは、スレッドは、例外が発生したときに呼び出されますキャッチされないハンドラを設定するオプションを持っている

Fron Androidのマニュアルhere

無効setDefaultUncaughtExceptionHandler(EHのThread.UncaughtExceptionHandler):スレッドが急激キャッチされない例外に終了し、他のハンドラがそのスレッドのために定義されていない場合、デフォルトのハンドラを設定 が呼び出さ。

未捕捉例外処理は、最初にスレッドによって制御され、次にスレッドのThreadGroupオブジェクトによって制御され、最後にデフォルトの捕捉されない例外ハンドラによって制御されます。スレッドに明示的なキャッチされていない例外ハンドラセットがなく、スレッドのスレッドグループ(親スレッドグループを含む)がuncaughtExceptionメソッドを特化していない場合、デフォルトのハンドラのuncaughtExceptionメソッドが呼び出されます。

デフォルトのキャッチされていない例外ハンドラを設定することで、アプリケーションは、システムの「デフォルト」動作を既に受け入れているスレッドに対して、キャッチされない例外(特定のデバイスまたはファイルへのロギングなど)提供されます。

デフォルトのキャッチされていない例外ハンドラは、無限再帰を引き起こす可能性があるため、スレッドのThreadGroupオブジェクトを通常延期するべきではないことに注意してください。

また、setDefaultUncaughtExceptionHandlerは静的メソッドであり、アプリケーションによって作成されたすべてのスレッドに適用されることに注意してください。

深く掘り下げた場合、Androidフレームワークは、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

関連する問題