如何在CodenameOne中获取设备上的堆栈跟踪信息?

时间:2018-06-18 19:11:24

标签: exception codenameone throwable

我的应用程序在模拟器中运行良好,在Android手机上很棒,但在Apple手机上,我在启动过程中遇到“ArrayIndexOutOfBounds:0”错误,没有任何解释。如何进入stacktrace进行调试?

这是一个很好的开始(来自https://www.codenameone.com/blog/handling-the-exception.html

Display.getInstance().addEdtErrorHandler(new ActionListener() {
 public void actionPerformed(ActionEvent evt) {
    evt.consume();
    Log.p("Exception in AppName version " +Display.getInstance().getProperty("AppVersion", "Unknown"));
    Log.p("OS " + Display.getInstance().getPlatformName());
    Log.p("Error " + evt.getSource());
    Log.p("Current Form " + Display.getInstance().getCurrent().getName());
    Log.e((Throwable)evt.getSource());
    Log.sendLog();
}});

但是1)没有堆栈跟踪和2)Log.sendLog需要订阅。我是一个自雇的业余爱好者,在我生命的这个阶段买不起订阅。我已经尝试了几种通常在Java中的途径:

   ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
   PrintStream ps = new PrintStream(baos);
   System.setOut(ps);

唉,CodenameOne中没有System.setOut。但是neato,在Throwable中有一个StackTraceElement []!

   for (StackTraceElement ste: throwable.getStackTrace()) {
      container.add(new SpanLabel(ste.toString()));
   }

不编译。根据我的IDE(可能来自Java 8)和github上的源代码(https://github.com/codenameone/CodenameOne/blob/master/vm/JavaAPI/src/java/lang/Throwable.java),StackTraceElement出现在Throwable中,但CLDC11.jar中的代码却没有出现。无论哪种方式,java.lang.StackTraceElement都不是CodenameOne发行版的一部分,并且不受支持。当然会很方便(阅读功能要求)!

虽然CodenameOne有一个内置的错误处理程序可以弹出一个对话框,但这个错误对最终用户来说是无用的,因为他们不知道对于没有堆栈跟踪的开发人员意味着什么并且没用。在我的情况下,错误只发生在设备上,而不是在模拟器中,所以我可以告诉我没有办法访问堆栈跟踪。这是对的吗?

功能请求:在错误处理对话框中包含堆栈跟踪(即使作为可扩展+列表)和/或包括从代码获取堆栈跟踪的方法。尽我所知,堆栈跟踪只能转到stdout。感谢您阅读所有这些!

2 个答案:

答案 0 :(得分:2)

Android非常简单,因为你可以使用logcat但是对于iOS我通常会在存储中存储一个包含调试信息的字符串,你可以设置一个按钮(在工具栏中)以将日志显示为弹出对话框或可能是新表单,以便它更容易阅读。

Storage storage = Storage.getInstance();
String log = (String) storage.readObject("debugLog");
log += "your debug string\n";
storage.writeObject("debugLog", log);

或者您可以使用偏好

Preferences.set("debugLog", Preferences.get("debugLog", null) + "your debug string" + "\n");

答案 1 :(得分:0)

此黑客将堆栈跟踪作为字符串获取

class LogCapture extends Log
{   Log oldLog;
    StringWriter myWriter;
    LogCapture() 
    { oldLog = Log.getInstance();
      install(this);  
    }
    protected Writer createWriter() throws IOException 
    {   return(myWriter = new StringWriter());
    }
    public String dispose()
    {
        install(oldLog);
        return(myWriter.toString());
    }
}

然后

    public static String getStackTrace(Throwable t)
{
    LogCapture cap = new LogCapture();
    Log.e(t);
    return cap.dispose();   
}