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循环复制;
再如双字符串联结:
Strings=“abc”+strVar;
Strings=“abc”.concat(strVar);
(有的编译器将语句1编译成构造StringBuffer,这时语句2将省空间)
特点:正规化瘦身,工作量大。瘦身率:依情况而定
4。合并类(非常规减肥)
将若干子类合并到父类中,或将若干个不冲突的类合并成一个类。通过type或classID来判别具体实例属于哪个类,再应用公有的方法使用switch()转接到更名后的方法。
如publicpaint()可能会调用privatepaint4XXXVies()。
设计时还可使用重名变量进一步节省空间,但代码可读性大大降低。
特点:破坏面向对象设计、维护困难。瘦身率:高(合并一个类大约可瘦身1-3K)
5。挤压实现(疯狂减肥)
属于变态减肥方法,包括:
用直接访问变量的方式取代getter/setter方法
废除常量定义(一些混扰工具可完成);
减少变量和字符串。
特点:破坏面可读性、维护艰难。瘦身率:低(在临界值时使用)
上述瘦身方法均是针对已经成型产品。而在程序开始设计时,瘦身的考虑也是相当重要的。下面根据实际情况举一些小例子:
1。保留计算结果
在前面提到的瘦身技术中包括getter/setter方法替换方式,而对一些类的属性可考虑固化变量法,即在初始化时将此属性值记录到类的成员变量中。但此属性必须是初始就确定、运行中不会改变或极少改变(改变的地方要重赋值);另外,由于此方法不能实现lazyloading,故要求属性是被“必然访问”的属性。
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里边我们看到有obfuscatorsetting的部分,在这里我们可以对工程的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/>:当你想合用第三方的混淆器时,指定第三方混淆的配置。还有的是,ProGuard3.x提供了一个字节代码优化器(默认是false),当你用ProGuard混淆器时可以用此元素来优化代码:
<obfuscator unless="test" enable="true" name="ProGuard" > <parameter name="optimize" value="true" /> </obfuscator
如果你想几个obfuscator一起用,也可以,只要连着写几个<obfuscator/>就可以了。
[/size]