第二章 技术背景
2.1 J2ME
2.1.1概念
J2ME(Java 2 Micro Edition)作为Java 2的一个组成部分,它与J2SE、J2EE并称。根据Sun的定义:J2ME是一种高度优化的Java运行环境,主要针对消费类电子设备的,例如蜂窝电话和可视电话、数字机顶盒、汽车导航系统等等。J2ME技术在1999年的JavaOne Developer Conference大会上正式推出,它将Java语言的与平台无关的特性移植到小型电子设备上,允许移动无线设备之间共享应用程序。
J2ME 在设计其规格的时候,遵循着“对于各种不同的装置而造出一个单一的开发系统是没有意义的事”这个基本原则。于是 J2ME 先将所有的嵌入式装置大体上区分为两种:一种是运算功能有限、电力供应也有限的嵌入式装置(比方说PDA 、手机);另外一种则是运算能力相对较佳、并请在电力供应上相对比较充足的嵌入式装置 (比方说冷气机、电冰箱、电视机顶盒 (set-top box))。因为这两种型态的嵌入式装置,所以Java 引入了一个叫做Configuration 的概念,然后把上述运算功能有限、电力有限的嵌入式装置定义在Connected Limited Device Configuration,即受限连接设备配置,简称CLDC规格之中;而另外一种装置则规范为 Connected Device Configuration,即连接设备配置,简称CDC规格。也就是说, J2ME 先把所有的嵌入式装置利用Configuration 的概念区隔成两种抽象的型态。
2.1.2架构
J2ME与J2SE和J2EE相比,J2ME总体的运行环境和目标更加多样化,但其中每一种产品的用途却更为单一,而且资源限制也更加严格。为了在达到标准化和兼容性的同时尽量满足不同方面的需求,J2ME的架构分为Configuration(配置)、Profile(简表)和Optional Packages(可选包)。它们的组合取舍形成了具体的运行环境。
Configuration主要是对设备纵向的分类,分类依据包括存储和处理能力,其中定义了虚拟机特性和基本的类库。已经标准化的配置有CLDC和CDC。
Profile建立在Configuration基础之上,一起构成了完整的运行环境。它对设备横向分类,针对特定领域细分市场,内容主要包括特定用途的类库和API。CLDC上已经标准化的Profile有Mobile Information Device Profile ( MIDP)和Information Module Profile(IMP),而CDC上标准化的Profile有Foundation Profile(FP)、Personal Basis Profile(PBP)和Personal Profile(PP)。
可选包独立于前面两者提供附加的、模块化的和更为多样化的功能。目前标准化的可选包包括数据库访问、多媒体、蓝牙等等。
下面的图表描述了不同的虚拟机、配置和简表之间的关系。它同时把 J2SE API 和它的 Java 虚拟机进行了比较。虽然 J2SE 虚拟机通常被称为一种 JVM,但是 J2ME 虚拟机KVM 和 CVM 都是 JVM 的子集。KVM 和 CVM 均可被看作是一种 Java 虚拟机,不过它们是J2SE JVM的压缩版,并特定于J2ME。
图2 不同虚拟机关系表
2.1.3 MIDlet及其运行机制
在前面一节中我们介绍了CLDC/MIDP的软件体系结构,这里给出的MIDlet的概念——在MID设备上运行的Java程序被称为MIDlet,这种命名的方法如同我们熟悉的Applet。下面将深入讨论一些MIDlet所涉及的内容。
MIDlet
与通常的Java程序相比MIDlet有比较大的不同,从某种意义上来说MIDlet更类似与Applet,简而言之与J2SE程序相比MIDlet没有main()这个程序初始入口点,同时MIDlet也不能调用Runtime.exit() 和System.exit()方法来中止虚拟机的运行。如果调用的话将会抛出SecurityException异常 。MIDlet是在MID设备上运行的Java程序每一个MIDlet必须派生自抽象类。 javax.microedition.midlet.MIDlet的继承体系如下图所示:
图3 MIDlet的继承体系
下面给出一个具体的MIDlet示例
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
public class MyMIDlet extends MIDlet{
public MyMIDlet{
}
protected void startApp() throws MIDletStateChangeException{
}
protected void pauseApp(){
}
protected void destroyApp(boolean arg0){
}
throws MIDletStateChangeException{
}
}
MIDlet的lifecycle
下面将分析MyMIDlet的结构来介绍其的运行的Lifecycle。
对源程序进行观察可以发现MIDlet程序的运行是由startApp(),pauseApp()和destroyApp()这3个方法控制的,它们都在javax.microedition.midlet.MIDlet中定义,所有的MIDlet都必须实现这3个方法。
startApp()方法用于标志一个MIDlet的开始执行。 与MyMIDlet程序的构造函数不同。startApp()不光是在初始化完一个MIDlet时执行。只要该MIDLet被从Paused态激活(变为Active态),startApp()就会被调用。
pauseApp()方法标志着MIDlet进入了 Pause状态。而destroyApp()方法则标志着MIDlet进入destroyed态。
MIDlet的执行实际是通过AMS即Application Management software来进行管理的。AMS是位于操作系统级别上用来管理MIDlet运行的底层机制的总称,所谓MIDlet state(MIDlet状态)就是它一手操办控制管理的。MIDlet state确保了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如何控制MIDlet的状态改变。程序员也可请求MIDlet的状态的变换通过调用resumeRequest, notifyPaused, notifyDestroyed这三个方法 。
我们的MyMIDlet程序先把destroyApp() 的unconditional