记录 Android Activity 中未处理的异常

jda*_*ski 2 java android exception

我创建了一个类,BaseActivity extends AppCompatActivityAndroid 应用程序中的所有活动都继承自该类。

在本课程中,我打算捕获所有未处理的异常,因此我可以将它们写入本地 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){

    }
}

}
Run Code Online (Sandbox Code Playgroud)

澄清一下: ApplicationError只是一个模型类,它使用DBFlow.

问题

每次在活动中发生未处理的异常(无论它是什么)时,都会发生两件奇怪的事情:

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

谁能帮我这个?或者有更好的方法来解决这个问题吗?

jda*_*ski 5

在AAG的回答的帮助下,我终于解决了这个问题。

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

@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){

        }
    }

}
Run Code Online (Sandbox Code Playgroud)