java - 在 Android Activity 中记录未处理的异常

标签 java android exception

我创建了一个类 BaseActivity extends AppCompatActivity,我在 Android 应用程序中的所有 Activites 都继承自该类。

在这门课中,我打算捕获所有未处理的异常,这样我就可以将它们写入本地 SQLite 数据库以供以后检查/发送到远程服务器。

下面附上整个类的代码:

public class BaseActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    final Thread.UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();

    Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
            Log.e("Uncaught Exception", paramThrowable.getMessage());
            logError(paramThrowable);
            defaultHandler.uncaughtException(paramThread, paramThrowable);
        }
    });
}

private void logError(final Throwable paramThrowable){
    try {
        ApplicationError error = new ApplicationError();

        String stackTrace = "";
        for (int i = 0; i < paramThrowable.getStackTrace().length; i++) {
            stackTrace += paramThrowable.getStackTrace()[i].toString() + "\n";
        }

        Throwable tmp = paramThrowable;
        int j = 0;
        while ((tmp = tmp.getCause()) != null && j < 5) {
            j++;
            stackTrace += "Coused by:\n";
            for (int i = 0; i < tmp.getStackTrace().length; i++) {
                stackTrace += tmp.getStackTrace()[i].toString() + "\n";
            }
        }

        Log.e("Saving error...", "");

        String deviceInfo = "";
        deviceInfo += "OS version: " + System.getProperty("os.version") + "\n";
        deviceInfo += "API level: " + Build.VERSION.SDK_INT + "\n";
        deviceInfo += "Manufacturer: " + Build.MANUFACTURER + "\n";
        deviceInfo += "Device: " + Build.DEVICE + "\n";
        deviceInfo += "Model: " + Build.MODEL + "\n";
        deviceInfo += "Product: " + Build.PRODUCT + "\n";

        error.mDeviceInfo = deviceInfo;
        error.mErrorMessage = paramThrowable.getMessage();
        error.mStackTrace = stackTrace;

        error.save();

        Log.e("Saved error:", error.mErrorMessage + "\n" + error.mStackTrace);
    }catch(Exception e){

    }
}

}

澄清一下: ApplicationError 只是一个模型类,它使用 DBFlow 处理保存到数据库的操作。

问题

每次在 Activity 中发生未处理的异常(不管它是什么)时都会发生两件奇怪的事情:

  1. logError() 方法被调用了不止一次,有时甚至是 8-10 次。查看日志,我可以看到它们具有几乎相同的时间戳。
  2. 设备屏幕上显示消息“XXX 应用程序已停止”(这很好),但在关闭它后应用程序挂起,我需要从应用程序设置屏幕强制停止。

谁能帮我解决这个问题?还是有更好的方法来解决这个问题?

最佳答案

AAG's answer 的帮助下,我终于解决了这个问题.

@AAG 你是对的,每次调用任何 Activity 中的 onCreate() 方法时都会添加异常处理程序。

@AAG 但是您不使用 defaultHandler 是错误的。我必须使用它,Android 才能正确处理应用程序崩溃。

感谢您的帮助!

这是固定的代码:

public class BaseActivity extends AppCompatActivity {

    public static Context applicationContext = null;
    public static Thread.UncaughtExceptionHandler defaultHandler = null;
    public static Thread.UncaughtExceptionHandler exceptionHandler = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if(defaultHandler == null){
            defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        }

        if(applicationContext == null){
            applicationContext = getApplicationContext();
        }

        if(exceptionHandler == null){
            exceptionHandler = new Thread.UncaughtExceptionHandler() {
                @Override
                public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
                    Log.e("Uncaught Exception", paramThrowable.getMessage());
                    logError(paramThrowable);
                    defaultHandler.uncaughtException(paramThread, paramThrowable);

                }
            };

            Thread.setDefaultUncaughtExceptionHandler(exceptionHandler);
        }
    }

    private static void logError(final Throwable paramThrowable){
        try {
            ApplicationError error = new ApplicationError();

            String stackTrace = "";
            for (int i = 0; i < paramThrowable.getStackTrace().length; i++) {
                stackTrace += paramThrowable.getStackTrace()[i].toString() + "\n";
            }

            Log.e("Saving error...", "");

            Throwable tmp = paramThrowable;
            int j = 0;
            while ((tmp = tmp.getCause()) != null && j < 5) {
                j++;
                stackTrace += "Coused by:\n";
                for (int i = 0; i < tmp.getStackTrace().length; i++) {
                    stackTrace += tmp.getStackTrace()[i].toString() + "\n";
                }
            }

            String deviceInfo = "";
            deviceInfo += "OS version: " + System.getProperty("os.version") + "\n";
            deviceInfo += "API level: " + Build.VERSION.SDK_INT + "\n";
            deviceInfo += "Manufacturer: " + Build.MANUFACTURER + "\n";
            deviceInfo += "Device: " + Build.DEVICE + "\n";
            deviceInfo += "Model: " + Build.MODEL + "\n";
            deviceInfo += "Product: " + Build.PRODUCT + "\n";

            error.mDeviceInfo = deviceInfo;
            error.mErrorMessage = paramThrowable.getMessage();
            error.mStackTrace = stackTrace;

            error.save();

            Log.e("Saved error:", error.mErrorMessage + "\n" + error.mStackTrace);
        }catch(Exception e){

        }
    }

}

关于java - 在 Android Activity 中记录未处理的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35876515/

相关文章:

java - TextView 在 AsyncTask 中给出 NullPointerException

java - 如何为 Ivy/Ant 指定 Eclipse 的 java.home 设置

Android的悬浮窗加上FLAG_SHOW_WHEN_LOCKED失效

c++ - 将 GetLastError() 变成异常

c# - 找不到 OWIN HttpListener

java - 如何将@ExceptionHandler与Spring拦截器一起用于两个JSP页面?

java - 如何将文件路径写入txt.file?

java - Spring继承不起作用

Android - 不要在旋转时刷新 Google Maps v2

java - 将 setText 设置为 EditText 时出现 NullPointerException - onDateSet