13

onCreate()で、UncaughtExceptionハンドラーを次のように設定しました。

Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {
       Log.e(getMethodName(2), "uncaughtException", throwable);
       android.os.Process.killProcess(android.os.Process.myPid());
    }
});

正常に動作しますが、ユーザーに強制終了ダイアログを表示するというシステムのデフォルトの動作に戻したいと思います。

KillProcess()呼び出しをコンパイラに置き換えようとするとthrow throwable、コンパイラは、try/catchで呼び出す必要があると文句を言います。

try / catchで囲む場合:

Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {
        try {
            Log.e(getMethodName(2), "uncaughtException", throwable);
            throw throwable;
        }
        catch (Exception e) {           
        }
        finally {               
        }
    }
});

throw throwableコンパイラは、try/catchで囲む必要があると文句を言います。

そのスローアブルを再スローするにはどうすればよいですか?その情報を除いてLog.e()、システムは以前とまったく同じように動作します。デフォルトのUncaughtExceptionハンドラーを設定したことはありません。

4

4 に答える 4

20

試す:

public class CustomExceptionHandler implements UncaughtExceptionHandler {

    private UncaughtExceptionHandler defaultUEH;

    public CustomExceptionHandler() {
        this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
    }

    public void uncaughtException(Thread t, Throwable e) {
        Log.e("Tag", "uncaughtException", throwable);
        defaultUEH.uncaughtException(t, e);
    }
}

その後 Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler());

この答えから適応。

于 2012-06-27T22:14:40.057 に答える
3

デフォルトのキャッチされない例外ハンドラーを設定すると、その中で例外を消費することが期待されます。uncaughtExceptionこれは、例外を宣言していないという事実に反映されています。

それを再投げる明白な理由はないはずです。2回目のログに出力されるだけで、とにかくスレッドは停止します。本当にそれが必要な場合は、throwableをラップしRuntimeExceptionて再スローするだけです。

于 2012-06-27T22:20:19.903 に答える
2

javadocによると、Throwableを再スローする理由はありません。単に無視されます。 スレッドはこの時点で終了しています。終了する前に試行する最後のアクションを設定しているだけです。

議論のために、スローアブルを再スローしたい場合は、次のようにします。

public void reThrow(Throwable t) {
    if (RuntimeException.class.isAssignableFrom(t.getClass())) {
        throw (RuntimeException)t;
    } else if (Error.class.isAssignableFrom(t.getClass())) {
        throw (Error) t;
    } else {
        throw new UndeclaredThrowableException(t);
    }
}
于 2012-06-27T22:21:11.537 に答える
1

まず、例外を再スローする必要はありません。uncaughtException()例外を消費しません。ただし、デフォルトのキャッチされない例外ハンドラのメソッドを呼び出す必要があります。だから、

class MyUEH implements UncaughtExceptionHandler {
  private static final UncaughtExceptionHandler default = Thread.getDefaultUncaughtExceptionHandler();

    public void uncaughtException(Thread t, Throwable e) {
        Log.e("Tag", "uncaughtException", throwable);
        default.uncaughtException(t, e);
    }
}

次に、プロセスを自分で強制終了する必要はありません。デフォルトのUEHは、呼び出し時にそれを処理します。

第3に、デフォルトのUEHは、標準のクラッシュ(強制終了)ダイアログをユーザーに表示します(または表示させます)。メソッドがハングした場合(たとえば、IOを実行しているため)、メソッドが終了するまでユーザーにはクラッシュダイアログが表示されないことに注意してください。

于 2012-06-27T22:30:14.547 に答える