首页 文章

如何重新抛出异常

提问于
浏览
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());
    }
});

它工作正常,但我想恢复系统向用户显示强制关闭对话框的默认行为 .

如果我尝试用 throw throwable 替换 KillProcess() 调用,编译器会抱怨我需要用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包围 .

我如何重新扔掉那个扔掉的?这样,除了信息量之外,系统的行为与以前完全一样:因为我从未设置过默认的UncaughtException处理程序 .

4 回答

  • 18

    尝试:

    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());

    改编自this答案 .

  • 2

    如果设置默认的未捕获异常处理程序,则应该在其中使用异常 . 这反映在 uncaughtException 没有声明任何异常的事实上 .

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

  • 1

    没有理由重新抛出Throwable,因为javadoc, it is simply ignored.此时线程正在终止,你需要在退出之前尝试.1036412_s .

    为了争论,如果你确实想重新抛出一个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);
        }
    }
    
  • 3

    首先,您不需要重新抛出异常 . 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),那么在您的方法退出之前,用户将看不到崩溃对话框 .

相关问题