移动信息设备描述

  移动信息设备描述(Mobile Information Device Profile,MIDP)是一套Java应用编程接口(Application Programmer's Interfaces(APIs))。它们与有限连接设备配置(Connected Limited Device Configuration,CLDC)一起向诸如蜂窝电话等移动信息设备提供了一个完整的Java应用运行环境。MIDP中含有下列API包:javax.microedition.lcdui--用户界面(UI)API,它为MIDP应用提供了一整套实现用户界面的功能特性;javax.microediton.rms--移动信息设备描述提供了一种让MIDlets永久储存并在以后可以取回数据的机制。javax.microedition.midlet--这个MIDlet包明确定义了MIDP应用,也定义了和应用环境之间的交互。javax.microedition.io--移动信息设备还描述包括基于有限连接设备配置GenericConnection框架的网络支持。

  MIDP是向下兼容的,即MIDP2.0的手机能玩MIDP1.0的游戏。

  MIDP1.0有容量限制,软件不能超过64K。

  如果你的MIDP2.0手机不能玩MIDP1.0的游戏,那只能说明厂商没有严格按照MIDP标准开发游戏和硬件。

一、移动信息设备描述MIDP的

      如前文所述,sun在CLDC之上定义了MIDP(Mobile Information Device Pro-file)层,用以提供对UI、永久存储介质(persistinace storage)、和网络等更高层的(相对于CLDC)支持。那么,让我们来具体看看MIDP的类库。

      MIDP由四个javax.microedition包组成,它们包括:

      javax.microedition.rms-----关于永久存储介质(注:rms是Record Management System的缩写)
      javax.microedition.midlet--定义了MIDlet的框架,以及MIDlet与环境的交互。
      javax.microedition.io------网络支持
      javax.microedition.lcdui---UI(User Interface)(注:UI分为high-level和low-level两种API。)

      注:如果在加上语言和实用类(java.lang和java.util)则有六个。

二、MIDPlet

      MIDP中定义的应用程序称为MIDlet。任何一个MIDlet都是javax.microedition.midlet.MIDlet的子类,必须继承自javax.microedition.midlet.MIDlet。这很显而易见。我们在J2SE中编过Applet,Applet就必须继承自java.applet.Applet。是不是很类似。请看下图,说明了MIDlet的继承体系。

┌────────────────┐
│javax.microedition.midlet.MIDlet│
└────────────────┘

┌──────┐
│MyMIDlet│
└──────┘

图1 MIDlet的继承体系

      本文是“j2me的基本介绍”系列文章的后续,在基础篇中,将主要介绍MIDP的组织结构,和MIDlet的LifeCycle,并通过一个实例,编写一个MIDlet程序。

三、编译一个简单的MIDlet,并执行。

      下面我先给出一个简单的HelloWorld程序,然后进行分析。

===============================源程序==================================

//HelloWorld.java,一个最简单的MIDlet程序。

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class HelloWorld extends MIDlet implements CommandListener {

private Command exitCommand;
private TextBox tb;

public HelloWorld(){
exitCommand =new Command("Exit",Command.EXIT,1);
tb =new TextBox("Hello MIDlet","Hello,World!",15,0);
tb.addCommand(exitCommand);
tb.setCommandListener(this);
}

protected void startApp(){
Display.getDisplay(this).setCurrent(tb);
}

protected void pauseApp(){
}

protected void destroyApp(boolean u){
}

public void commandAction(Command c,Displayable d){
if (c ==exitCommand){
destroyApp(false);
notifyDestroyed();
}
}
}

===============================源程序完================================

      该程序显示“HelloWorld”字符串。程序本身非常简单,如果你熟悉JavaApplet编程的话,你会发现与Applet很类似。好,我们先把它编译,运行一下看看。

      编译之前的准备:

      硬件:因为是Java,所以内存最少有128MB以上,CPU最好是PII或更高。
平台:最好是win2000,win98的中文显示会有问题,解决起来比较麻烦。Linux我没有试过,英文我想应该都没什么问题,但中文显示我估计可能会有些麻烦如果有试过的朋友,请一定告诉我。

      SDK:你需要有(下述软件都可在sun网站上免费下载)

      1。Java 2 SDK 1.3或以上。

      2。J2ME Wireless Toolkit 1.0.3

      以下可选:

      sun的IDE:Forte for java。(如果你上的是宽带,或不是自己付网费的话 ^-^)下载好后,先安装JDK1.3,(具体关于安装和设置我就不详述了,想来大家都很清楚。如果您不清楚,请参考相应资料。)在安装J2ME Wireless Toolkit 1.0.3,它会自动找到您的JDK1.3,并作相应设置。如果您不用命令行的话,环境变量也不用设置直接可在图形界面上运行,非常方便。关于环境变量的设置请自己参考手册。

      编译的步骤:

      如果你按上述已经安装好JDK和J2mewtk,请按以下步骤编译,实际上是非常简单的:

      (注:下述默任JDK安装在c:\JDK1.3,J2ME Wirless Toolkit 安装在c:\J2mewtk\)

      1. 开始->程序->J2ME Wirless ToolKit 1.0.3->KToolBar
      2. 这时会出现"J2ME Wirless ToolKit"窗口,点"New project"按键,在Project name项填:HelloWorld;在MIDLet Class Name填:HelloWorld。点击Creat project。
      3. 这时会出现Setting for project对话窗,采取默认即可。点击ok。
      4. 这时请注意,因为没有down sun的IDE,所以你要手工把你事先编辑好的HelloWorld.java放置在c:\j2mewtk\apps\HelloWorld\src\目录下。这时,按“Build”键,如果一切正常,将提示编译完毕。这时在device下拉选单中选定你想要的设备,再按“run”键,终于大功告成。你可以多选几个不同设备,感受一下,不错吧。

四、MIDlet的Lifecycle

      在上一节里,我们已经成功编译并运行了一个简单的MIDlet程序。现在,让我们来分析一下MIDlet的结构,和其Lifecycle。

      通过对源程序的观察,我们可以发现MIDlet程序的运行是由startApp(),pauseApp()和destroyApp()这3个方法控制的。它们在javax.microedition.midlet.MIDlet中定义。所有的MIDlet都必须有这3个方法。顾名思义startApp()方法用于标志一个MIDlet的开始执行。不过这里要注意一点,与HelloWorld程序的constrctor不同。startApp()不光是在初始化完一个MIDlet时执行,只要该MIDLet被从Paused态激活(变为Active态),startApp()就会被调用。pauseApp()方法标志着MIDlet进入Pause态。而destroyApp()方法标志着MIDlet进入destroyed态。(注意:这里严格的讲应该说成:方法被调用并成功返回标志着...)

      看完上面的描述,大家可能会满头雾水,又是方法,又是状态的,什么跟什么吗?这还得从MIDlet的执行机制讲起。MIDlet的执行是通过Application Management software来管理的。这玩意儿是处在操作系统级别上来管理MIDlet运行的底层机制的总称,所谓MIDlet state(MIDlet状态)就是它一手操办,控制管理的。MIDletstate确保了AMS随时可以消灭该MIDlet,同时MIDlet也有办法进入一个Pause态,并可再次激活。MIDlet State 分为Paused,Active,destroyed三种。当AMS创生一个新的MIDlet实体时,对应于MIDlet,表现为其constructor被调用,进入Paused状态。当所有的准备工作都做好后,AMS判断现在MIDlet可以运行了,于是调用MIDlet.startApp()方法。进入Active态。当AMS决定要把MIDlet转入Paused态,就会调用MIDlet.pauseApp()方法,MIDlet就会暂停执行,通常Paused态会用于释放所占资源。当AMS判断MIDlet不再需要,就会调用MIDlet.destroyApp(),MIDlet被消灭。请注意我上述是站在AMS的角度在谈AMS如何控制MIDlet的状态改变。程序员也可请求MIDlet的状态的变换,通过调用resumeRequest,notifyPaused,notifyDestroyed这三个方法。

      例如,我在上一节给出的例子中有如下程序片段:
...
public void commandAction(Command c,Displayable d){
if (c ==exitCommand){
destroyApp(false);
notifyDestroyed();
}
...

      这里先把destroyApp()的unconditional值置为false,抛出一个MIDletStateChangeException 异常,表示MIDlet这时还不想被destroy。notityDestroyed()通知AMSMIDlet进入destroyed态。具体的细节请参阅MIDP API文档。

      下面给出一个最简单的MIDlet流程:

===========================FlowMIDlet.java================================
import javax.microedition.midlet.*;
public class FlowMIDlet extends MIDlet {
public void startApp() {
System.out.println( "In startApp..." );
pauseApp();
}
public void pauseApp() {
System.out.println( "In pauseApp..." );
destroyApp( true );
}
public void destroyApp( boolean unconditional) {
System.out.println( "In destroyApp..." );
}
}

===========================FlowMIDlet.java完===============================

      关于MIDlet状态的改变可以用下图表示:

destoryApp()
+----------------------->--------------------------+
| |
new() +========+ startApp() +========+ destroyApp() +===========+
----->| Paused |------------->| Active |--------------->| Destroyed |
+========+ +========+ +===========+
| pauseApp() |
+---------<------------+


图1 MIDlet的状态转变

      这里还要说几句闲话,关于AMS,其作用不止是控制MIDlet的运行状态。它实际上际上负责了MIDlet的整个运行机制。关于AMS进一步的描述,请参见王森老师的文章-“利用Java撰写手机应用-Java Application Manager篇”(《程序员》,12期,2001)。注意其中JAM就是AMS。

五、关于MIDlet Suites

      在上一节里我主要从应用程序执行角度讲述了MIDlet的lifecycle。但实际上MIDlet的lifeCycle是包括了从获取(retrieve),安装,运行,卸载的一个整体。

      通过ASM来进行控制。其中运行这一步包括了我已经讲过的三种状态的改变。ASM为MIDlet的获取,安装,运行,卸载提供了一个运行环境。

      如果你的MIDlet想要下载到实机上去运行,你就必须将其打包为一个jar文件

      一个Jar文件中可能有多个MIDlet,我们把在同一Jar文件中的MIDlet的集合称为MIDlet suite。一个打包好的MIDlet包括两部分:一个.jad文档,即描述文档。和一个.jar文档。其中.jad文档是一个文本文档,记录MIDlet的属性名称和属性值。

      .jar文件是一个压缩包,其中有MIDlet的清单(Manifest.mf),编译好的类(即MIDlet),图片,文本等其他资源。

      如下图所示:

+==============================+
|MIDlet Suite(.Jar) |
| |
| +----------+ +-----------+ |
| |MIDlet-1 | |MIDlet-2 | |
| +----------+ +-----------+ | + 描述文档(.jad文档)
| +-----------+ |
| |Manifest.mf| +---------+ |
| +-----------+ | other | |
| | resouce | |
| +---------+ |
+==============================+

      关于描述文档和清单文档的详细介绍,以及MIDlet属性值代表的含义和填写方法。

      请参考王森老师的文章-“利用Java撰写手机应用-Java Application Manager篇”

      (《程序员》,12期,2001)。文章中写的很明白,小弟就不一一介绍了。
(来源:http://www.mobjava.com;http://www.javafan.net/article/20060420212421524.html

中程在线