j2mepolish中obfuscator(混淆器)的应用
[size=14]我们知道在j2mepolish带有一个ant构件工具,且有一个build.xml文件。在build.xml里边定义了一个工程的编译(compile)、混淆(obfuscate)、打包(package).....等命令。所以很多人都喜欢用j2mepolish来的ant来管理一个j2me工程的编译打包工作,即使他们没用到polish, 避免了用ant时写build文件的麻烦。
build.xml:
<build
symbols="ExampleSymbol, AnotherExample"
imageLoadStrategy="foreground"
fullscreen="menu"
usePolishGui="true"
>
<!-- midlets definition -->
<midlet class="de.enough.polish.example.MenuMidlet" name="Example" />
<!-- project-wide variables - used for preprocessing -->
<variables>
<variable name="update-url" value="http://www.enough.de/update" />
</variables>
<!-- obfuscator settings -->
<obfuscator name="ProGuard"
useDefaultPacakge="true"
unless="test" />
<!-- debug settings -->
<debug showLogOnError="true"
verbose="true"
level="error"
if="test"
>
<filter package="de.enough.polish.example" level="debug" />
<filter class="de.enough.polish.ui.Gauge" level="info" />
</debug>
</build>
现在我主要谈谈polish中的obfuscator(混淆器)的应用。我们知道J2ME的应用开发极大地受到了设备的限制。通常可下载类应用限制在几百K左右,设备本身限制在64k、100k、128k等不等。尽管现在的手机的内存可以达到1G(有些可以用内存卡),但一个应用程序的大小还是尽可能小好,因为这可能影响程序的性能。
下边是网上关于j2me应用程序瘦身的办法:
引用
1。 使用混扰obfuscate(正规减肥)
Java语言采用按名索引链接。包名,类变量名被保留在class的常量表中,混扰后有意义的名称被短的无意义的字串所代替,从此减少程序大小。同时混扰同时去掉了行号等调试信息(如果编译选项中未去掉)。另外,通常的混扰工具还将从未用过的方法、变量删除,从而减少程序空间。
特点:不涉及源程序,易于维护。瘦身率 10%-30%
2。“优化”包结构(常规减肥)
一些混扰工具不改变包的结构,也不能减少包的层次,如“com.pip.kstock.util.Tools”可能被混扰成“b.a.a.b.t”;而“com_pip_kstock_util.Tools”则可能成为“b.t”.这是配合混扰工具的减肥措施。另外,要明确分离被保护的包,因为被保护的包的所有类的包名都被保护。
特点:不改变类结构及源程序。瘦身率:3%-5%
3。优化程序(专业减肥)
此减肥方法是对源程序的调整,诸如“注释掉不用的方法”(若混扰工具不能做到的话);去掉无用的赋值和语句;优化语句;针对空间优化算法等。
如使用arraycopy替代for循环复制;
再如双字符串联结:
String s = “abc” + strVar;
String s = “abc”.concat(strVar);
(有的编译器将语句1编译成构造StringBuffer,这时语句2将省空间)
特点:正规化瘦身,工作量大。瘦身率:依情况而定
4。合并类(非常规减肥)
将若干子类合并到父类中,或将若干个不冲突的类合并成一个类。通过type或classID来判别具体实例属于哪个类,再应用公有的方法使用switch()转接到更名后的方法。
如public paint()可能会调用private paint4XXXVies()。
设计时还可使用重名变量进一步节省空间,但代码可读性大大降低。
特点:破坏面向对象设计、维护困难。瘦身率:高(合并一个类大约可瘦身1-3K)
5。挤压实现(疯狂减肥)
属于变态减肥方法,包括:
用直接访问变量的方式取代getter/setter方法
废除常量定义(一些混扰工具可完成);
减少变量和字符串。
特点:破坏面可读性、维护艰难。瘦身率:低(在临界值时使用)
上述瘦身方法均是针对已经成型产品。而在程序开始设计时,瘦身的考虑也是相当重要的。下面根据实际情况举一些小例子:
1。保留计算结果
在前面提到的瘦身技术中包括getter/setter方法替换方式,而对一些类的属性可考虑固化变量法,即在初始化时将此属性值记录到类的成员变量中。但此属性必须是初始就确定、运行中不会改变或极少改变(改变的地方要重赋值);另外,由于此方法不能实现lazy loading,故要求属性是被“必然访问”的属性。
2。集中分支语句
在CLDC规范中,有一个J2SE虚拟机之外的东西,即preverify,对应到类文件中是StackMap结构。如果你的一个函数代码中没有分支语句,包括没有异常处理,StackMap将缺席并使用缺省的内容。这在节省空间上有好处。
另外,StackMap结构的单元尺寸和代码段长度有关,所以避免写太长的方法。
3。关于变量初值
java的成员变量的初值不象写起来那样简单,他们是在类的初始化函数块中被赋予的。如果你想赋的初值同缺省的值一致,那么请省下5-6个字节吧。(不要因程序风格而犹豫,写上你的注释)
(该篇文章引用:http://clwu.bokee.com/1632798.html)
可见混淆器(obfuscator)是优化一个j2me应用程序的主要利器。我们来看回polish中的obfuscator, 在polish中带有三个obfuscator: "ProGuard", "YGuard", "RetroGuard", 其中默认是用"ProGuard"。在上边的build.xml里边我们看到有obfuscator setting 的部分, 在这里我们可以对工程的obfuscation设置。当然,如果你不想用obfuscator, 只要把这个settings 部分注释掉就行了。
下边来看看obfuscator的设置:
<obfuscator unless="test" enable="true" name="ProGuard" >
<keep class="com.company.dynamic.SomeDynamicClass" />
<keep class="com.company.dynamic.AnotherDynamicClass" />
<parameter name="scriptFile" value="../scripts/obfuscate.script" />
</obfuscator>
其主要属性与元素:
属性name: 指定当前obfuscator的名称,其中"ProGuard"是默认的,如果你想用其的的obfuscator,只要在build.xml中指定相应的classPath就可以了。
元素<keep/>: 保留你不想参与混淆的类,留给程序动态加载。这个很好用,当你混淆某个工程后,运行时却发现有部分的类找不到,显示
java.lang.ClassNotFoundException, 这时你可以用<keep/>把这个类保留下来,给程序动态加载。(我用polish混淆时碰过这情况,不知用其它混淆时(如JB)有没有??^_^)
元素<parameter/>: 当你想合用第三方的混淆器时,指定第三方混淆的配置。还有的是,ProGuard 3.x 提供了一个字节代码优化器(默认是false),当你用ProGuard混淆器时可以用此元素来优化代码:
<obfuscator unless="test" enable="true" name="ProGuard" >
<parameter name="optimize" value="true" />
</obfuscator
如果你想几个obfuscator一起用,也可以,只要连着写几个<obfuscator/>就可以了。
[/size]