优化J2ME应用程序

原创 2002年06月26日 13:14:00

作者:Eric Giguere 编译:Sean
2002年2月27号


如果要说J2ME应用程序和J2SE应用程序有什么不同的地方的话,那就是他们各自被限制运行的环境。
很多J2ME系统的主要的瓶颈是存储和运行应用程序的可用内存数量。举例来说,当前许多MIDP设备,他们
限制给应用程序的内存数量就只有50K或更少,离可能要求兆级的基于服务端J2SE环境有段很长的距离。
由于你在开发中会很容易就遭遇这些限制,所以在这篇J2ME技术提示中,你会学到如何让你的应用程序占用最
少的内存。你将用这些技术减少MIDlet占用的空间,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程序。
注意上面演示的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 Wireless Toolkit打包以后,这个MIDlet例子仅仅4K多一点。

减少size的第一步是通过减少应用程序功能来移除一些不必要的类。你的应用程序的每个特性都是真的必要的吗?
你的用户能否忍受没有铃声和哨声?让我们来建立最小版本的应用程序。注意到MIDlet例子已经是相当小的了。

第二步着眼于应用程序定义的内部类,特别是匿名类。记住每一个类文件都有一定相应的空间开支。甚至最微不足道的
类也需要成本:
  public class foo {
        // nothing here
  }
编译这个类,你可以发现你得到一个占用几乎200字节空间的class文件。一个匿名类一般用途是用来实现事件监听。
MIDlet例子定义了两个listener。一个简单优化就是让MIDlet的主类实现CommandListener和ItemStateListener
两个接口,删除里面的listener代码。记住多个对象可以使用相同的listener。如果需要区别开来,
可以传递参数给commanAction和itemStateChanged方法。

内部类也会通过其他方面膨胀代码,因为编译器必须产生不同的变量和方法来允许一个内部类访问封装类里面的私有信息。

第三步是最大程度使用内置的类。举个例子,在基于CLDC的程序中不要建立你自己的集合类。尽量使用内置的Hashtable
和Vector。设计MIDP应用也是一样。MIDlet例子定义了一个Form子类来创建它的主form,但它还能被很容易地直接创建:
  mainForm = new Form( "MainForm" );
  mainForm.addCommand( okCommand );
  mainForm.setCommandListener( listener );
这里没有对和错的问题,这只是需要考虑的一些简单的东西。

第四步是取消你应用程序的继承关系。你可能已经将代码分解成一个或多个抽象类,这是个被推荐的能提高代码重用
的OOD设计方法。也许会跟你学到的东西有抵触,但去简化继承层次更加说的过去。如果你的抽象类——可能来自其他项目——
只是被继承了一次,那简化继承关系就显得特别有理由。MIDlet例子扩展了BaicMIDlet类,但两个类很容易组合成一个。

第五步是缩短你的包名,类名,方法名和数据成员名。看上去这一步显得很愚蠢,但一个class文件保存了很多字符信息。
缩短他们的名字你会减少clas文件的size。这个办法节省的东西不会很多,但当遍及到多个类时他们会增加。包名特别
应该被缩短。因为MIDP应用程序完全是独立的,你能完全避免包名——不会有机会跟该设备其他类的名字冲突。MIDlet例子
可以从com.j2medeveloper.techtips 包里面移出来。

注意缩短名字不是你手工要做的那些东西,我们可以使用一个名叫“扰乱器”的工具来做。扰乱器的主要目的是
为应用程序“隐藏”代码,它反编译程序的时候使程序变成一些几乎无法阅读的东西。这个过程的另外一个作用就是减少了程序的size。
那上因为隐藏代码主要通过重新为方法和数据成员命名。这里有个开发源代码的扰乱器叫RetroGuard的免费工具来自
http://www.retrologic.com,并且上面还有许多商业用的包

最后,关注一些数组的初始化。(MIDlet例子没有做任何数组初始化,但这是程序很重要的一步)当编译完以后,一个数组初始化
代码像这样:
int arr[] = { 0, 1, 2, 3 };
实际产生的代码如下:
    arr[0] = 0;
    arr[1] = 1;
    arr[2] = 2;
    arr[3] = 3;
如果想研究的话,可以使用java2sdk一起发布的将字节代码分解成一个class的javap工具(使用-c参数)。你可能会惊讶和不满
你所看到的结果。两种可选的办法是(1)把数据编码到一个String里面,运行时解码到数组,或(2)将数据作为二进制文件保存
到程序包里面并在运行时用class loader的getReourceAsStream方法访问。

这里说的东西只是一些指导,并且在这里提到的不是每一步都适合每一个J2ME应用程序。然而,他们大部分都可以应用这个MIDlet例子。
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();
        }
    }
}

 


原文:http://wireless.java.sun.com/midp/ttips/appsize/

优化J2ME应用程序

优化J2ME应用程序 如果要说J2ME应用程序和J2SE应用程序有什么不同的地方的话,那就是他们各自被限制运行的环境。很多J2ME系统的主要的瓶颈是存储和运行应用程序的可用内存数量。举例来说,当前许多...
  • SmartJavaer
  • SmartJavaer
  • 2007年02月26日 13:19
  • 784

J2ME中文教程之J2ME技术概述

随着移动通信的突飞猛进,移动开发这个新鲜的字眼慢慢成为开发者关注的热点。在网上进行的最近一份调查显示,有24.34%的受访者涉足嵌入式/移动设备应用开发,这个数字可能略高于实际的比例,但也足可说明嵌入...
  • lpy123456
  • lpy123456
  • 2007年01月16日 12:37
  • 676

J2ME技术入门之一——J2ME程序的开发过程

       在进行J2ME开发以前,必须首先了解J2ME程序的开发过程,只有熟悉了开发过程以后才可以了解如何进行J2ME程序的开发。由于运行环境以及针对平台的不同,J2ME的开发过程和J2SE的开发...
  • Mailbomb
  • Mailbomb
  • 2005年06月23日 18:49
  • 2811

用Eclipse做J2Me开发的前期配置

 我也是一个初学者,从一个初学者的角度上讲,就是要尽可能的详细,因为这个东西稍微配置不对,或者是那里没有注意到,就会走不少的弯路,所以我在这里把配置讲得非常的详细,以图文的形式展示,以免你看了不知道所...
  • fenglibing
  • fenglibing
  • 2007年09月05日 23:01
  • 10305

J2ME入门之HelloWorld

引言  前面几篇文章已经介绍了Eclipse及其工作环境的安装、配置过程,并完成各项相关准备工作。因此从本文开始将讲述如何使用前面配置好的Eclipse开发环境来创建J2ME项目,开始真正的J2ME开...
  • runner0592
  • runner0592
  • 2006年08月10日 23:35
  • 4109

eclipse中配置j2me,简单运行j2me程序

1.安装好jdk2.去官网上下载好eclipse,去eclipseme.org上下载eclipseme,http://www.oracle.com/technetwork/java/download-...
  • snrqtdhuqf
  • snrqtdhuqf
  • 2011年01月20日 10:09
  • 2388

J2ME游戏按键处理方法简述

J2ME游戏按键处理方法简述 摘要:在游戏当中很多时候,要求按键有更多的响应方式,我们的问题就多起来了。  正文:1.ScanKey()方法这种方法使在keyPressed()、keyRelease(...
  • NetMicrobe
  • NetMicrobe
  • 2006年11月04日 15:37
  • 1944

Android和j2me对比

本文主要介绍如何把J2ME游戏移植到Android平台的方法,如果你是个J2ME的游戏开发者,并且想把一些J2ME游戏快速地迁移到Android平台,那么相信本文会对你有所帮助。当然,如果您非说可以安...
  • codinglu
  • codinglu
  • 2011年06月25日 19:45
  • 521

Eclipse上搭建Nokia手机的J2ME开发环境

-->安装Nokia Development Suite 2.2 最新版本的Nokia开发包为2.2版本,支持J2ME2.0(包括1.0)。下载地址:http://www.forum.nokia.c...
  • herrapfel
  • herrapfel
  • 2005年06月24日 16:58
  • 1808

三、第一个J2ME程序[J2ME入门开发教程]

在这之前我们做一个统一,把所有的代码默认编码方式都设置为UTF-8。 我们以一个简单的计算器为例来设计运行我们的第一个JavaME程序:首先点击菜单File->New->J2ME中的J2ME M...
  • CHUANGHUI
  • CHUANGHUI
  • 2013年02月26日 18:38
  • 920
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:优化J2ME应用程序
举报原因:
原因补充:

(最多只允许输入30个字)