⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 优化j2me程序大小.txt

📁 优化J2ME程序大小 作者Eric Giguere是来自Sybase下属iAnywhere Solutions的软件开发人员。他致力于手持设备和无线计算领域的Java技术。他是滑铁卢大学的数学学士和
💻 TXT
字号:
要把J2ME程序与J2SE程序区分开来,其依据就是J2ME运行所处的受限环境。多数J2ME系统的主要 
受限条件就是可以存储和运行程序所需内存的大小。例如,许多MIDP设备限制应用程序的尺寸不 
大于50K,这远远不及Server端J2SE运行环境下那些成兆的程序。实际应用中,程序会很容易超出 
这些限制条件。通过本篇您将学到一些减小程序尺寸大小的技巧,并在下面的例子中实践这些技 
术。这个例子MIDlet仅仅显示一个文本框并在其内容改变时发声。 


代码:-------------------------------------------------------------------------------- 
package com.j2medeveloper.techtips; 
import javax.microedition.lcdui.*; 
public class BeforeSizeOptimization extends 
BasicMIDlet { 
public static final Command exitCommand = 
new Command( "Exit", 
Command.EXIT, 1 ); 
public BeforeSizeOptimization(){ 
} 
protected void initMIDlet(){ 
getDisplay().setCurrent( new Mainform() ); 
} 
public class Mainform extends form { 
public Mainform(){ 
super( "Mainform" ); 
addCommand( exitCommand ); 
append( textf ); 
setCommandListener( new CommandListener(){ 
public void commandAction( Command c, 
Displayable d ){ 
if( c == exitCommand ){ 
exitMIDlet(); 
} 
} 
} 
); 
setItemStateListener( 
new ItemStateListener() { 
public void itemStateChanged( 
Item item ){ 
if( item == textf ){ 
AlertType.INFO.playSound( 
getDisplay() ); 
} 
} 
} 
); 
} 
private TextField textf = 
new TextField( "Type anything", null, 
20, 0 ); 
} 
} 
-------------------------------------------------------------------------------- 

虽然这个MIDlet在此仅作为一个例子,但使用的尺寸优化技巧可以适用于任一J2ME的profile上。 
注意,上面的MIDlet类需要下面的辅助类: 

代码:-------------------------------------------------------------------------------- 
package com.j2medeveloper.techtips; 
import javax.microedition.lcdui.*; 
import javax.microedition.midlet.*; 
public abstract class BasicMIDlet extends MIDlet { 
private Display display; 
public BasicMIDlet(){ 
} 
protected void destroyApp( boolean unconditional ) 
throws MIDletStateChangeException { 
exitMIDlet(); 
} 
public void exitMIDlet(){ 
notifyDestroyed(); 
} 
public Display getDisplay(){ return display; } 
protected abstract void initMIDlet(); 
protected void pauseApp(){ 
} 
protected void startApp() 
throws MIDletStateChangeException { 
if( display == null ){ 
display = Display.getDisplay( this ); 
initMIDlet(); 
} 
} 
} 
-------------------------------------------------------------------------------- 

用J2ME WTK打包时,本例子MIDlet占用4K空间。 
减小尺寸的首要步骤就是通过修正程序的功能实现来去掉多余的类。程序的所有功能确实必须都 
实现吗?用户可以不需要这些“附属功能”吗?要设计尽可能小的程序,这里的MIDlet例子已经 
相当小了。 
第二步就是深入考察程序定义的内部类,特别是匿名类。记住,每个类文件都有一定量的与之相 
关的系统开销。即便最普通的类也有系统开销。 
public class foo { 
// nothing here 
} 
编译上边的类,生成的类文件大约200byte大小。比如实现一个事件监听器,就是对匿名类的常见 
使用。在例子MIDlet中就定义了两个此类的监听器。接下来进行的最简单的优化就是,让主 
MIDlet类实现CommandListener和ItemStateListener接口,并把监听器代码移至此处。记住,多 
个对象可以使用同样的监听器。必要时,可以使用传递至commandAction和itemStateChanged方法 
的参变量来区分它们。 
内部类也可使代码过大,因为编译器必须生成特殊的变量和方法,以便内部类可以访问包含它们 
的类的私有内容。请参考内部类的规范以获取更多信息。 
第三步,尽量使用现有的类。例如,基于CLDC的profile没有构造集合类,所以我们可以用内建的 
Hashtable和Vector类来实现之。构造MIDP程序时也可采用此法。例子MIDlet中定义了一个form字 
类来生成主表,可以容易的如下直接生成: 
mainform = new form( "Mainform" ); 
mainform.addCommand( okCommand ); 
mainform.setCommandListener( listener ); 
这里没有正确或者错误的答案,只是要推敲。 
第四步就是破坏程序的继承关系。你也许把相关的代码放到一个或多个抽象类中,这是OOD中为提 
高程序间代码重用的推荐做法。虽然破坏继承关系与你所学知识相违背,但简化的继承关系更有 
意义。特别的,当你的的抽象类?D?D可能来自其他项目?D?D仅仅被继承一次时,破坏继承关系的 
结果不言而喻。例如,例子MIDlet继承了BasicMIDlet类,但两者合并为一个类。 
第五步就是要缩短名字长度,如包名、类名、方法名和数据元素名。看起来有些蠢,但一个类文 
件确实包含太多的符号信息。缩短各量的名字可以缩小生成的类文件尺寸。这种节省不会特别明 
显,但多个类中进行总加的结果还是可观的。包名对减小尺寸来讲特别合适。MIDP程序是完全自 
我包容的,完全可以不使用包名,因为在手持设备上包名根本不可能与其他类名冲突。例子 
MIDlet中,可以把com.j2medeveloper.tchtips包名去掉。 
注意,一般来讲,缩短名字不需要手工去做,要用一个“混淆器”去做。“混淆器”的主要功能 
是“隐藏”程序代码,使之不能通过反编译读出。它的副作用是减小了程序的尺寸。因为隐藏过 
程主要通过更改方法和数据成员的名字来完成。有一个开源的混淆器称为RetroGuard,可以免费 
从 http://www.retrologic.com 得到。也有一些商业包可用。(当为基于CLDC的profile混淆时,记 
得在预校验之前混淆,否则混淆器将使类文件中的预校验数据失效。) 
最后,深入数组的初始化。(例子MIDlet没有做数组初始化,但对程序来说初始化是重要的一步) 
在编译时,一个数组初始化声明如下所示: 
int arr[] = { 0, 1, 2, 3 }; 
而实际生成代码的过程如下所示: 
arr[0] = 0; 
arr[1] = 1; 
arr[2] = 2; 
arr[3] = 3; 
这个过程可以通过使用Java 2 SDK中附带的javap工具把二进制代码反编译成类文件去看(使用-c 选项)。也许你会诧异于看到的内容,特别当你希望看到的是一排排二进制常数时。有两种方法可以让你看不到反编译的程序代码,
(1)把数据编码为字符串,运行时解码之,或者
(2)把数据存为 二进制文件并与程序打包,用类装载器的getResourceAsStream方法在运行时存取之。以上只是一些指导性的方法,对每个J2ME程序而言,这里没有具体到步骤。但是多数方法可以应用的本例。优化后的MIDlet如下所示: 

代码:-------------------------------------------------------------------------------- 
import javax.microedition.lcdui.*; 
import javax.microedition.midlet.*; 
public class ASO extends MIDlet 
implements CommandListener, 
ItemStateListener { 
private Display display; 
private form mainform; 
private TextField mainformTF = 
new TextField( "Type anything", null, 
20, 0 ); 
public static final Command exitCommand = 
new Command( "Exit", 
Command.EXIT, 1 ); 
public ASO(){ 
} 
public void commandAction( Command c, 
Displayable d ){ 
if( c == exitCommand ){ 
exitMIDlet(); 
} 
} 
protected void destroyApp( boolean unconditional ) 
throws MIDletStateChangeException { 
exitMIDlet(); 
} 
public void exitMIDlet(){ 
notifyDestroyed(); 
} 
public Display getDisplay(){ return display; } 
protected void initMIDlet(){ 
mainform = new form( "Mainform" ); 
mainform.addCommand( exitCommand ); 
mainform.setCommandListener( this ); 
mainform.setItemStateListener( this ); 
mainform.append( mainformTF ); 
getDisplay().setCurrent( mainform ); 
} 
public void itemStateChanged( Item item ){ 
if( item == mainformTF ){ 
AlertType.INFO.playSound( getDisplay() ); 
} 
} 
protected void pauseApp(){ 
} 
protected void startApp() 
throws MIDletStateChangeException { 
if( display == null ){ 
display = Display.getDisplay( this ); 
initMIDlet(); 
} 
} 
} 
-------------------------------------------------------------------------------- 

关于作者:Eric Giguere是来自Sybase下属iAnywhere Solutions的软件开发人员。他致力于手持设备和无线计算领域的Java技术。他是滑铁卢大学的数学学士和数学硕士,写了很多有关计算的文章

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -