Java 在Android中捕获线程中的所有异常

Java 在Android中捕获线程中的所有异常,java,android,Java,Android,我希望捕获由活动类中的任何语句引起的异常,以便防止任何崩溃。无法测试应用程序可能使用的所有可能场景。我想在应用程序中提供一个带有按钮的警告对话框或文本框来报告问题,但不希望应用程序崩溃。有没有办法做到这一点 我尝试使用构造函数在类级别抛出异常,但没有帮助。Try-Catch不能对每一条语句都执行,所以有什么好的防崩溃解决方案可以捕获整个活动类中的异常呢 来自主线程,例如在onCreate()中 Thread thread = Thread.currentThread(); thread.setU

我希望捕获由活动类中的任何语句引起的异常,以便防止任何崩溃。无法测试应用程序可能使用的所有可能场景。我想在应用程序中提供一个带有按钮的警告对话框或文本框来报告问题,但不希望应用程序崩溃。有没有办法做到这一点


我尝试使用构造函数在类级别抛出异常,但没有帮助。Try-Catch不能对每一条语句都执行,所以有什么好的防崩溃解决方案可以捕获整个活动类中的异常呢

来自主线程,例如在onCreate()中

Thread thread = Thread.currentThread();
thread.setUncaughtExceptionHandler(uncaughtExceptionHandler);

从主线程,例如在onCreate()中

Thread thread = Thread.currentThread();
thread.setUncaughtExceptionHandler(uncaughtExceptionHandler);

是的,您可以创建一个
ExceptionHandler
类并收集崩溃记录

 public class ExceptionHandler implements
        Thread.UncaughtExceptionHandler {
    private final Activity myContext;
    private final String LINE_SEPARATOR = "\n";

    public ExceptionHandler(Activity context) {
        myContext = context;
    }

    public void uncaughtException(Thread thread, Throwable exception) {
        StringWriter stackTrace = new StringWriter();
        exception.printStackTrace(new PrintWriter(stackTrace));
        StringBuilder errorReport = new StringBuilder();
        errorReport.append("************ CAUSE OF ERROR ************\n\n");
        errorReport.append(stackTrace.toString());

        errorReport.append("\n************ DEVICE INFORMATION ***********\n");
        errorReport.append("Brand: ");
        errorReport.append(Build.BRAND);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Device: ");
        errorReport.append(Build.DEVICE);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Model: ");
        errorReport.append(Build.MODEL);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Id: ");
        errorReport.append(Build.ID);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Product: ");
        errorReport.append(Build.PRODUCT);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("\n************ FIRMWARE ************\n");
        errorReport.append("SDK: ");
        errorReport.append(Build.VERSION.SDK);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Release: ");
        errorReport.append(Build.VERSION.RELEASE);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Incremental: ");
        errorReport.append(Build.VERSION.INCREMENTAL);
        errorReport.append(LINE_SEPARATOR);

        Intent intent = new Intent(myContext, CrashActivity.class); //start a new activity to show error message
        intent.putExtra("error", errorReport.toString());
        myContext.startActivity(intent);

        android.os.Process.killProcess(android.os.Process.myPid());
        System.exit(10);
    }
}
现在,在MainActivity中,使用以下命令初始化ExceptionHandler:

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this));
    setContentView(R.layout.activity_main);
}

是的,您可以创建一个
ExceptionHandler
类并收集崩溃记录

 public class ExceptionHandler implements
        Thread.UncaughtExceptionHandler {
    private final Activity myContext;
    private final String LINE_SEPARATOR = "\n";

    public ExceptionHandler(Activity context) {
        myContext = context;
    }

    public void uncaughtException(Thread thread, Throwable exception) {
        StringWriter stackTrace = new StringWriter();
        exception.printStackTrace(new PrintWriter(stackTrace));
        StringBuilder errorReport = new StringBuilder();
        errorReport.append("************ CAUSE OF ERROR ************\n\n");
        errorReport.append(stackTrace.toString());

        errorReport.append("\n************ DEVICE INFORMATION ***********\n");
        errorReport.append("Brand: ");
        errorReport.append(Build.BRAND);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Device: ");
        errorReport.append(Build.DEVICE);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Model: ");
        errorReport.append(Build.MODEL);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Id: ");
        errorReport.append(Build.ID);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Product: ");
        errorReport.append(Build.PRODUCT);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("\n************ FIRMWARE ************\n");
        errorReport.append("SDK: ");
        errorReport.append(Build.VERSION.SDK);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Release: ");
        errorReport.append(Build.VERSION.RELEASE);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Incremental: ");
        errorReport.append(Build.VERSION.INCREMENTAL);
        errorReport.append(LINE_SEPARATOR);

        Intent intent = new Intent(myContext, CrashActivity.class); //start a new activity to show error message
        intent.putExtra("error", errorReport.toString());
        myContext.startActivity(intent);

        android.os.Process.killProcess(android.os.Process.myPid());
        System.exit(10);
    }
}
现在,在MainActivity中,使用以下命令初始化ExceptionHandler:

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this));
    setContentView(R.layout.activity_main);
}

“测试应用程序可能使用的所有可能的场景是不可能的。”-我认为这不一定是真的。“一个好的防崩溃解决方案”修复导致运行时异常的bug将是一个好的开始。捕捉异常是一回事,实际上,以任何常规方式从应用程序中进行有意义的恢复基本上是不可能的。@JoeC我已经对应用程序进行了许多场景测试,但最好保持应用程序中错误的更好记录,并防止可能由某个不必要的因素导致的崩溃。警告:您希望的唯一原因是这样做是为了生成日志,而不是为了防止崩溃。OutOfMemoryException通常表示一个严重的错误,而NullPointerException总是表示一个错误。这些异常在生产代码中的任何情况下都不应该发生。请记住,异常处理是为了处理异常情况,而不是为了处理代码中的错误。@EJoshuaS我理解您关于提到的异常的观点应该在开发点检查,但是有大量具有不同API和RAM的设备可用,其他异常可能会崩溃。由于一些未经检查的场景,可能会出现崩溃,我希望通过将它们推到我的服务器上来跟踪这些场景。看到崩溃通常不是一个很好的用户体验。“测试应用程序可能使用的所有可能场景是不可能的。”-我不认为这是真的。“一个好的防崩溃解决方案”修复导致运行时异常的bug将是一个好的开始。捕捉异常是一回事,实际上,以任何常规方式从应用程序中进行有意义的恢复基本上是不可能的。@JoeC我已经对应用程序进行了许多场景测试,但最好保持应用程序中错误的更好记录,并防止可能由某个不必要的因素导致的崩溃。警告:您希望的唯一原因是这样做是为了生成日志,而不是为了防止崩溃。OutOfMemoryException通常表示一个严重的错误,而NullPointerException总是表示一个错误。这些异常在生产代码中的任何情况下都不应该发生。请记住,异常处理是为了处理异常情况,而不是为了处理代码中的错误。@EJoshuaS我理解您关于提到的异常的观点应该在开发点检查,但是有大量具有不同API和RAM的设备可用,其他异常可能会崩溃。由于一些未经检查的场景,可能会出现崩溃,我希望通过将它们推到我的服务器上来跟踪这些场景。看到崩溃通常不是很好的用户体验。