情景
在自定义库中遇到某些 RuntimeException:如 java.lang.NullPointerException。使用自定义的日志类,如“XXXLog.e(e)”。会出现无法追踪错误发生的位置(堆栈信息只打印到自定义库外面)。但是用原生的
e.printStackTrace();
方法却可以打印完整的堆栈信息,进而追踪自定义库内部的错误。
原因
很可能是自定义日志类“XXXLog”内部使用
e.fillInStackTrace();
方法配合
String msg = Log.getStackTraceString(e.fillInStackTrace());
来实现错误堆栈信息打印。这是一个坑。因为有时候 (Exception e) 中 e 用 Throwable.backtrace 变量来存储堆栈信息。
一旦调用 e.fillInStackTrace()来使用这些信息,就会导致 backtrace 变量重置(backtrace == null),表示堆栈信息已处理。此时 Log.getStackTraceString(e.fillInStackTrace()) 指向的 e 中也就没有信息了。
解决
使用
ByteArrayOutputStream baos = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(baos));
String msg = baos.toString();
来获取堆栈信息。