一个异常日志捕获工具

2016-12-30  本文已影响0人  红烧排骨饭

为什么需要这个工具

在产品测试的时候,如果能在出现程序异常导致崩溃的情况下记录当时的现场,那么开发人员就能能够快速地定位到问题所在

这个工具能够提供什么功能

原理

如果线程因为一个无法捕获的异常而终止,可以使用一个实现了接口 Thread.UncaughtExceptionHandler 的类来进行着手处理。

在异常发生的时候,异常的有关信息会作为参数传入 Thread.UncaughtExceptionHandler 的 public void uncaughtException(Thread t, Throwable ex) 方法中去。我们只需要在这个方法中捕获异常日志,把日志保存到文件或者显示到界面上。

实现

新建一个类 CrashCanary,实现 Thread.UncaughtExceptionHandler 接口的方法

public class CrashCanary implements Thread.UncaughtExceptionHandler {
    @Override
    public void uncaughtException(Thread t, Throwable ex) {
    }
}

在这三个方法中,要做的事情有

获取异常日志

private String getCrashLogContent(Throwable ex) {
    Writer strWriter = new StringWriter();
    PrintWriter printWriter = new PrintWriter(strWriter);
    ex.printStackTrace(printWriter);

    Throwable nextCause = ex.getCause();
    while (nextCause != null) {
        nextCause.printStackTrace(printWriter);
        nextCause = nextCause.getCause();
    }
    String crashLogContent = strWriter.toString();
    printWriter.close();

    return crashLogContent;
}

格式化异常日志

将时间加上

private String formatCrashLog(String crashLogContent, long timeMillis) {
    return TextUtils.concat(
            ">>>>>>>>>>>>>> ", DateFormat.format(LOG_RECORD_TIME_FORMAT, timeMillis), ">>>>>>>>>>>>>> ",
            "\r\n",
            crashLogContent,
            "\r\n",
            "\r\n"
    ).toString();
}

保存异常日志到本地文件

public static void writeToFile(String dir, String fileName, String content, String encoder) {
    File file = new File(dir, fileName);
    File parentFile = file.getParentFile();
    OutputStreamWriter osw = null;
    BufferedWriter bw = null;
    try {
        if (!parentFile.exists()) {
            parentFile.mkdirs();
        }
        if (!file.exists()) {
            file.createNewFile();
        }
        osw = new OutputStreamWriter(new FileOutputStream(file, true), encoder);
        bw = new BufferedWriter(osw);
        bw.append(content);
        bw.append("\r\n");
        bw.flush();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        closeSilently(bw);
        closeSilently(osw);
    }
}

退出崩溃的App

private void exitApp() {
    android.os.Process.killProcess(android.os.Process.myPid());
    System.exit(1);
}

总结

原理很简单

如果线程因为一个无法捕获的异常而终止,可以使用一个实现了接口 Thread.UncaughtExceptionHandler 的类来进行着手处理。

套路很简单,就几个步骤

上一篇下一篇

猜你喜欢

热点阅读