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()用 a 替换调用,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没有声明任何异常的事实上。

应该没有明显的理由重新抛出它。它只会在日志中第二次打印出来,无论如何线程都会死掉。如果你真的想要那个,那么只需将可投掷包裹起来RuntimeException并重新投掷。

于 2012-06-27T22:20:19.903 回答
2

没有理由重新抛出 Throwable,根据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 将处理它。

第三,默认 UEH 将向用户显示(或导致显示)标准崩溃(强制关闭)对话框。请记住,如果您的方法挂起(例如,因为您正在执行 IO),那么在您的方法退出之前,用户将不会看到崩溃对话框。

于 2012-06-27T22:30:14.547 回答