[英]Restore stack trace from string
我正在实现一个 Android 应用程序并在发生异常时将异常保存到 SQLite 数据库中,因为用户的工作不应该被打断。 后来当他决定将异常发送到开发者控制台时,我想像这样抛出异常:
throw new Exception("Name of the exception");
有什么办法可以根据我之前保存的字符串再次重建堆栈跟踪吗?
仅使用字符串是不可能的。 但是,如果您可以将异常序列化为字节数组,并将其作为 blob 存储在您的 SQLite 数据库中。 单击此处了解如何将 blob 数据添加到 SQLite 数据库。
以下是如何将异常与字节数组相互转换:
public class Main {
public static void main(String args[]){
try{
throw new Exception("There is an error here!");
}catch(Exception e){
e.printStackTrace();
byte[] arr = convertExceptionToBlob(e); //save this as a BLOB in your database.
Exception retrieved = getExceptionFromBlob(arr);
retrieved.printStackTrace();
}
}
public static byte[] convertExceptionToBlob(Exception e){
try(ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutput out = new ObjectOutputStream(bos)){
out.writeObject(e);
return bos.toByteArray();
}catch(Exception ex){
return new byte[]{};
}
}
public static Exception getExceptionFromBlob(byte[] arr){
try (ByteArrayInputStream bis = new ByteArrayInputStream(arr);
ObjectInput in = new ObjectInputStream(bis)) {
return (Exception)in.readObject();
}catch(Exception ex){
return new Exception(ex.getMessage());
}
}
}
谢谢迪伦的回答! 我和我的同事讨论过,我们找到了另一个解决方案:
我们的想法是拆分堆栈跟踪元素并将其合并为一个字符串:
StringBuilder stackTraceStringBuilder = new StringBuilder();
for (StackTraceElement stackTraceElement : exception.getStackTrace())
stackTraceStringBuilder.append(String.format("%s|%s|%s|%d\n", stackTraceElement.getClassName(), stackTraceElement.getMethodName(), stackTraceElement.getFileName(), stackTraceElement.getLineNumber()));
this.stackTrace = stackTraceStringBuilder.toString();
将字符串恢复为堆栈跟踪元素非常简单:
RuntimeException runtimeException = new RuntimeException(message);
String[] stackTraceRows = stackTrace.split("\n");
StackTraceElement[] stackTraceElements = new StackTraceElement[stackTraceRows.length];
for (int i = 0; i < stackTraceRows.length; i++) {
String[] stackTraceRow = stackTraceRows[i].split("\\|");
stackTraceElements[i] = new StackTraceElement(stackTraceRow[0], stackTraceRow[1], stackTraceRow[2], Integer.parseInt(stackTraceRow[3]));
}
runtimeException.setStackTrace(stackTraceElements);
无论如何,Dylan 的解决方案看起来更好,但我不想保留这个选项。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.