登录J2ME
j2me有哪些日志记录解决方案?
我特别希望轻松排除"发行"版本的日志记录,以减少包装和内存占用。
解决方案
我已经在生产应用程序中使用了MIDPLogger达到可接受的水平,尽管我发现集成到应用程序中后,MIDPLogger的使用更多了,而不是套件中的另一个Midlet。我还找到了MicroLog,但没有用到任何细节。
MicroLog肯定会下注。它是Java ME(J2ME)的小型日志记录库,例如Log4j。它支持登录到控制台,文件,RecordStore,Canvas,Form,Bluetooth,串行端口(蓝牙,IR,USB),套接字(包括SSL),UDP,Syslog,MMS,SMS,电子邮件或者Amazon S3 。
http://sourceforge.net/projects/microlog/
如果我们正在使用Proguard进行预处理和混淆,那么我们可以拥有一个简单的日志记录类。
public class Log { public static void debug(final String message) { //#if !release.build System.out.println(message); //#endif } }
或者在任何需要的地方进行日志记录。现在,如果release.build属性设置为true,则该代码将被注释掉,这将导致一个空方法。 Proguard将删除所有使用空方法的方法。实际上,发布版本将删除所有调试消息。
编辑:
在库级别上考虑它(我正在研究J2ME库的映射),我可能已经找到了更好的解决方案。
public class Log { private static boolean showDebug; public static void debug(final String message) { if (showDebug) { System.out.println(message); } } public static void setShowDebug(final boolean show) { showDebug = show; } }
这样,最终开发人员可以在他/她感兴趣的库中启用日志级别。如果什么都不启用,则在最终产品混淆中将删除所有日志代码。甜的 :)
/贾努斯·西姆(JaanusSiim)
具有Symbian自己修改过的Sun虚拟机的Series60和UIQ电话具有"标准输出"重定向。
我们不仅可以捕获System.out,而且Throwable.printStackTrace()也可以工作。
在早期的手机上,我们将需要编写一个挂接到标准库服务器进程中的C ++应用程序。 Symbian生成了Redirector应用程序,该应用程序可以将VM标准输出捕获到控制台或者文件中。
在较新的手机上,引入了" redirect://" GCF协议,该协议可以将VM标准输出读取到Java byte []或者String对象中(我们希望在单独的MIDlet中完成此操作),并且Redirector应用程序已重写为Java。
在Series60 3rd Edition Feature Pack 2手机(和更高版本)中使用的最新J9 VM上,我们可能需要尝试使用" redirect:// test"。
我们可以在proguard中使用-assumenosideaffects来完成删除日志记录类的操作:
-assumenosideeffects public class logger.Logger {*;}
无需进行预处理。
我写了一个字节码优化器,由于类文件的格式,我们可以指向类名和函数的UTF编码,该编码允许我们使用MyClass.someFunc()输出日志(如果要获取类型,可以处理签名) ),这样我们就可以使用LINE&FILE宏来进行C风格的调试。
使用logger类的条件编译不能解决完全删除日志记录语句的问题,因为我们记录的日志往往比简单的字符串还要多。我们将查找变量值,然后将它们组合成字符串,例如:WhateverLog.log(" Loaded" + someclass.size()+" foos")。
现在,如果只留下WhateverLog.log的主体(如接受的解决方案中所示),我们仍然会留下很多不必要的代码,包括String串联(从而创建StringBuffer)。这就是为什么我们最好使用像proguard这样的字节码后处理工具(已经提到)的原因。 Proguard的-assumenosideeffects将允许其优化程序不仅删除日志记录语句,而且删除其结果仅由日志记录调用使用的所有代码。