1、MID(Mobile Information Device)特性
由于MID这类设备,在屏幕、内存、处理器等问题上有诸多限制,在手机或是PDA等MID上开发应用程序必须要考虑一些技术上的特殊点。
下面给出一些设备的特性:
·显示(display):96x54 (最小屏幕尺寸),1bit(最小色深,单色)
·输入设备: “one-handed keyboard”(指ITU-T手机键盘)
·“two-handedkeyboard” (指标准键盘,即QWERTY键盘)
·触摸屏。
·内存:128kb-MIDP组件。
8kb-应用程序生成的Persistent data(关于Persistent data,我会在将来讲RMS时,详细说明,这里有个概念就行了)
32kb-java runtime环境。
·网络: 双向的,无线的,间断的,带宽有限的网络
·内核(kernel):至少要能运行KVM
还有很多软件上的特性,如读写non-volatile内存(就是掉电后不会失去内容的内存,如flash)。读写无线设备接口的API,等等。
除了上诉技术上的问题,你还得注意你的程序要简单易用且稳定可靠。尤其是可靠性,你开发的是通讯设备,用户是不能忍受程序有什么纰漏而影响到通话的。
2、MIDP的类库
如前文所述,sun在CLDC之上定义了MIDP(Mobile Information Device Profile)层,用以提供对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)则有六个。
3、MIDPlet
MIDP中定义的应用程序称为MIDlet。任何一个MIDlet都是javax.microedition.midlet.MIDlet的子类,必须继承自javax.microedition.midlet.MIDlet。这很显而易见。我们在J2SE中编过Applet,Applet就必须继承自java.applet.Applet。是不是很类似。请看下图,说明了MIDlet的继承体系。
┌────────────────┐
│javax.microedition.midlet.MIDlet │
└────────────────┘
↓
┌──────┐
│MyMIDlet │
└──────┘
4、编译一个简单的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或更高。
平台:winxp
SDK:你需要有(下述软件都可在sun网站上免费下载)
·Java 2 SDK 1.3或以上。
·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/)
A. 开始->程序->J2ME Wirless ToolKit 1.0.3->KToolBar
B. 这时会出现"J2ME Wirless ToolKit"窗口,点"New project"按键,在Project name项填:HelloWorld;在MIDLet Class Name填:HelloWorld。点击Creat project。
C. 这时会出现Setting for project对话窗,采取默认即可。点击ok。
D. 这时请注意,因为没有down sun的IDE,所以你要手工把你事先编辑好的Hello World.java放置在c:/j2mewtk/apps/HelloWorld/src/目录下。这时,按“Build”键,如果一切正常,将提示编译完毕。这时在device下拉选单中选定你想要的设备,再按“run”键。
5、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,notify Destroyed这三个方法。
例如,我在上一节给出的例子中有如下程序片段:
public void commandAction(Command c,Displayable d)
{
if (c ==exitCommand)
{
destroyApp(false);
notifyDestroyed();
}
}
这里先把destroyApp()的unconditional值置为false,抛出一个MIDletStateChange Exception 异常,表示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状态的改变可以用下图表示:
图1 MIDlet的状态转变
这里还要说几句闲话,关于AMS,其作用不止是控制MIDlet的运行状态。它实际上际上负责了MIDlet的整个运行机制。
6、关于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),图片,文本等其他资源。
7、名词:
①MIDlet一个可以执行的应用程序基本单位。除了继承自javax.microedition. midlet.MIDlet之外,还包括让此类可以顺利执行的所有其它类和资源文件(只要是非class文件都称做资源文件)所构成的集合。
②MIDlet Suit 许多MIDlet所构成的集合,一般又叫做MIDlet应用程序套件。MIDlet Suite和MIDlet的关系,就很像Office与Word、Excel、PowerPoint、Access的关系。或者又叫做MIDP应用程序(MIDP Application),MIDP应用程序和MIDlet Suite这两个名词代表同一种东西。应用程序在部署时(不管是OTA或是非OTA)都以MIDlet Suite为单位进行。
③JAR文件(.jar文件) 就是包裹住MIDlet Suite的文件,属于ZIP压缩格式。
④JAD描述文件(.jad文件) 用来描述MIDlet Suite基本信息的文本文件,包括MIDlet Suite所包含之MIDlet相关信息(类名称、图标、程序名),或是MIDlet Suite之整体信息(文件大小、安全权限、证书等),这是一个外部文件(不存在JAR文件内部,独立存在的文件)。
⑤Java Application Manager(应用程序管理器) 负责将MIDlet Suite安装到机器上执行以及管理MIDlet生命周期之机制(或软件)总称。应用程序管理器会根据用户的需求来安装或移除MIDlet Suite,也可以根据用户的需求启动、停止MIDlet的运作。
8、关于应用程序管理器
应用程序管理器(Java Application Manager,JAM),也称做Application Management Software(AMS)。这是一个用来执行J2ME应用程序的原生程序(Native,代表通常用C/C++撰写而成),应用程序管理器负责管理在设备上所有的J2ME应用程序。
用程序管理器的实现方式会随着平台的不同而不同,但是大致上分成两种方式:
①在后台运作
这种类型的设计方式,使得一般的J2ME应用程序看起来和该平台一般的应用程序没有太大的差别。实际上应用程序管理器在后台运作着,用户很难感受到它的存在。这种实现方式可以在MIDP for Palm之中看到,Java HQ(MIDP.prc)就是这样的东西(如图所示)。
Java HQ(MIDP.prc)在后台运作
但是,如果程序开发人员安装了调试辅助工具(Developer.prc),仍然可以通过Java HQ之中Developer Preference里的MIDlets按钮来观察整个系统之中所安装的每一个J2ME应用程序。
②单一进入点
用户必须先进入应用程序管理器,然后才能启动个别的Java应用程序。这种应用程序管理器实现方式可以在Motorola、Nokia、SonyEricsson的手机上看到(如图示)
<shape id="_x0000_i1026" style="WIDTH: 106.5pt; HEIGHT: 107.25pt" alt="" type="#_x0000_t75"></shape><imagedata src="file:///C:/DOCUME~1/li/LOCALS~1/Temp/msohtml1/01/clip_image002.jpg" o:href="http://act.it.sohu.com/book/images/upload/67-4-4(1).jpg"></imagedata>
Nokia 7650 应用程序管理器
9、JAR与JAD
理论上,每个MIDP应用程序都是由一个JAD文件与一个JAR文件所构成,两者缺一不可。但是实际的情况下,在某些设备上部署MIDP应用程序时,该设备上的应用程序管理器并不要求一定要有JAD文件,有些甚至会自己产生对应的JAD。在MIDP 1.0时,是否有JAD文件无关痛痒。但是在MIDP 2.0之中,是否有JAD文件将涉及安全议题。
JAD文件是一个纯文本文件,所以内部都是一些属性和属性值。而JAR文件除了包含MIDlet以及其它相关的class文件(辅助类、程序库)之外,还包含了:
①资源文件 即MIDlet执行时所需要的文件,如图片、文本文件等,只要不是class文件,都称做资源。另外规范有规定,class文件不能当做资源来使用。
②清单文件(Manifest File,Manifest.mf)用来描述一个MIDP应用程序之基本信息,包括MIDlet Suite所包含之MIDlet相关信息(类名称、图标、程序名),或是MIDlet Suite之整体信息(名称、版本号码、制作者等)。这是一个内部文件(存在于JAR文件内部)。
10、MIDP执行环境
根据MIDP规范,所谓MIDP执行环境(MIDP Execution Environment)泛指MIDP应用程序在执行时期所能获取的资源。通常指的是下面几项东西所构成的集合,这些都是MIDP应用程序在执行时可以使用的资源:
①CLDC中所定义的类库。
②MIDP中所定义之类库。
③工具类。包括设计者自己所撰写的类、标准Optional Package所提供的类(例如WMA或MMAPI)、厂商专属程序库(例如Nokia UI API)或其它程序库(例如kXML或kSOAP)。MIDlet只能使用来自同一个JAR文件之中的所有类,无法使用其它MIDlet Suite之中的类。
④资源。MIDlet只能存取来自同一个JAR<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Time
10、MIDP的版本1.0和2.0
MIDP 1.0 提供了以下功能:
·显示工具箱
·用户输入方法
·持久性数据存储(使用简单的面向记录的数据库模型)
·基于 HTTP 1.1 的网络(使用 CLDC 通用连接框架)
Java 规范请求 (Java Specification Request, JSR)-37 中定义了 MIDP 1.0 标准。
MIDP 2.0提供了以下功能:
JSR-118 中定义了 MIDP 2.0 标准。
MIDP 2.0 于 2002 年 11 月正式发布,MIDP 2.0 的推出在一定意义上增强了 Java ME 的功能,主要体现在如下几个方面。
(1)支持操作图像的像素,支持 Alpha 通道。
(2)增强型的图形用户界面类 CustomItem,提高了高级界面类的表现力。
(3)Media 音频子系统填补了 MIDP 1.0 不支持声音播放的空白。
(4)Push 注册机制和安全模型增强了对 MIDlet 的控制。
(5)游戏开发包提高了游戏开发的效率。
(6)联网能力增强,可以支持 TCP/IP 甚至是 UDP 层的通信。