Java嵌入式开发之j2me.docx
《Java嵌入式开发之j2me.docx》由会员分享,可在线阅读,更多相关《Java嵌入式开发之j2me.docx(17页珍藏版)》请在冰点文库上搜索。
Java嵌入式开发之j2me
Java嵌入式开发之j2me
(二)-j2me
文章发布人:
gxy 共43人阅读 文字大小:
[大中小] 文字背景色:
J2ME之谜
第一节引言J2ME概述
到目前为止,大部分人都已非常熟悉Java2平台,以及Sun如何把Java技术分成三个版本(标准版、袖珍版以及企业版),Sun在1999年6月时推出了Java2袖珍版(J2ME)来满足消费电子和嵌入设备的需要。
J2ME是为了那些使用有限的能源、有限的网络连接(常常是无线连接)以及有限图形用户界面能力的设备开发的。
它最初的目标是16位或32位处理器,16MHz时钟频率,512K或更少内存的设备。
乍一看之下,J2ME就像一个没有绑定明显主题的松散的应用程序接口和技术规范。
我们想通过说它不是什么东西的方法来描述它,它不是一组用于台式机Java应用程序规范,如果你再观察仔细一些,你会发现所有的J2ME组件都围绕一个中心,这些中心被称为configuration(配置,Sun的市场营销资料也称它们designcenters,设计中心),它们中间的每一个都是用于消费电子和嵌入设备的特别的类。
Connectedlimiteddeviceconfiguration(有限连接设备配置,简称CLDC)这个配置定义了Java应用程序接口以及支持手持设备的技术,就像Sun的文档中所描述的那样,"devicesthatyouholdinyourhand(你握在手中的设备)"Palm序列手持设备可能是这一领域的设备的最好的例子,特别是它有开发CLDC的功能以及Palm设备运行期系统可用。
Connecteddeviceconfiguration(连接设备配置CDC)这个配置定义支持象Sun文档中所说,"devicesthatyouplugintoplugintothewall(你插入墙的设备)的设备的应用程序接口和技术,这样的设备的一个例子可能就是机顶盒。
这两种配置不同的地方就在于它们应用于的装置的能力,CLDC设备的处理器能力有限(与台式机系统比较),并且存储器大小一般也只在128KB到512KB之间,与此同时,CDC系统就不同了,它可能有32位或64位处理器,以及有限的存储容量,不过它的下限也得超过512K。
它遵循的原则就是,每个不同的能力硬件的配置都将被不同的虚拟机支持。
基于CDC的系统使用一个功能强劲的虚拟机,而基于CLDC系统的使用KVM(我过会儿会介绍)。
每个配置代表一种低水平的,基本的应用程序接口,在这两个相似基础之上是profile(简表),用于特殊设备的额外的应用程序接口。
我想通过看一张来自SUN提供的文档中的图表(参见图1)来解释这其中的关系。
图一解释配置和简表的体系结构J2ME的体系结构被横向地分成三层,纵向分成两部分。
配置包括一个控制配置核心类的虚拟机,具体的简表位于每个配置之上。
J2ME现在定义两个配置,ConnectedDeviceconfiguration(连接设备配置CDC)和限制性更强的ConnectedLimitedDeviceConfiguration(有限连接设备配置)。
简表的实现是Java应用程序接口的一个集合,用于适应被定义配置的应用程序接口提供的服务,简表是一个完整的运行环境,一个在简表上执行的应用程序不需要额外的支持类。
J2ME没有定义满足这两种配置的标准化用户接口,Sun也承认现在的消费设备多种多样,用户界面也各不一样,所以定义一个可用于所有用户的界面是一场失败的战争。
J2ME中的用户界面定义在简表中。
第二节J2ME的体系结构
现在个人计算机系统的数量和种类已经发展到无法控制的地步,请你想一想,你编写的程序运行在“信息家电”舞台的情景吧,这些信息家电包括呼叫器,行动电话,像Palm这样的个人数字助手(PDA),电视机顶盒,POS终端以及其他的消费电子设备。
现在全世界上光是手提电话生产商就有许多,更不用说别的家电设备了,而且每一种家电设备又有不同的特性和界面。
所以,你可以想到,Java应用程序的轻便性以及能够解决开发这么许多不同的设备程序的能力,使大家对J2ME有很大的期许。
当然,为了更好的开发这些信息家电,就要求把Java的精髓压缩进一个非常小的程序包中,这就是J2ME。
J2ME是一种通过许多部件和规范的技术,这众多的部件和规范帮助J2ME来满足这众多的消费产品的不同的需要。
和所有的爪哇程式语言技术一样,在它的核心属于一种虚拟机。
就像使用所有Java技术一样,J2ME的核心也在一种虚拟机中。
最初,用于J2ME应用程序虚拟机的被称作Kilobytevirtualmachine或简称KVM。
就像它名称的含义,KVM比较小,通常只有128K或更少。
这比起我们通常了解和使用的Java2标准版Java虚拟机(JVM)的32MB来说就小得多了。
用于连接虚拟机的是一系列配置和简表,它们提供了用于特定J2ME环境的类应用程序接口(见图二)。
每个配置和简表处理一般或具体的消费产品,配置和简表规范是由多种多样的设备生产商和用户共同开发并建立的。
配置是用于一组通用设备的最小的Java平台,常常归为一种横向的设备分组,相对来说,横向分组设备是那些共享相同的内存安排,通信带宽,能量需求以及用户能力的设备,一般认为配置能够提供这众多的设备的所有需求。
图二解释:
J2ME层次Java虚拟机是J2ME技术的核心,但是配置和简表提供特殊环境的类应用程序接口。
配置是用于一组通用设备的最小的Java平台,而简表则为具体的设备家族或特别的应用程序提供更具体的能力。
J2ME领域的新的开发者常常被这些事实困惑的,事实上,Sun的第一个配置(现在只是一种配置的引用实现)带有称为KVM的虚拟机引用实现,KVM满足配置的虚拟机的必要条件。
然而,Sun的KVM也可以被另外一个虚拟机所代替,现在,正是因为配置和虚拟机结合得有点紧密,因此导致了这么多的混乱。
另一方面,简表完善了配置,为某个具体的设备家族或某个具体的工业片段应用程序提供更高的性能。
换言之,简表为具体的纵向市场的设备比如说行动电话提供更多的性能。
这里的关键就是简表必须完善配置,没有配置和虚拟机提供核心类应用程序接口和运行期环境的话,简表也不会工作。
通常,简表为一种给定的垂直分组设备提供用户界面、输入法、持久性机制。
这类简表被认为是发展这些设备应用程序的完整的工具包。
我们见到最多的应用程序简表的例子就移动电话简表和个人数字助手(PDA)简表,其他简表为范围宽广的设备提供非常特殊的功能或应用程序可移植性,这方面的例子就是提供远程方法调用(RMI)功能的简表和提供统一银行事务的简表。
虚拟机、配置、简表…你是不是已经被搞迷糊了?
如果这样的话,我们就来简化一下J2ME体系结构吧。
如果你想为小型信息家电编写Java应用程序的话,你就需要两个前提:
一个配置和至少一个简表。
现在,一般是配置捆绑了虚拟机和一套针对你的平台所能够用的横向分组设备的Java类库。
其次,你至少还需要一个简表来为你的平台提供附加的Java类,这个简表通常会为你的设备提供用户界面、输入和数据库类。
有了这两个前提,你就了使用Java为你的设备编写应用程序的基本的J2ME环境。
第三节详细谈谈J2ME配置
J2ME可以在好几个不同的配置中进行配置。
就像先前提到的,每个配置为一组通用设备提供最小的Java平台,到目前为止,只有两种配置规范。
通过Java规范定义的这两种配置是ConnectedLimitedDeviceConfiguration(有限连接设备配置,CLDC)和ConnectedDeviceConfiguration(连接设备配置CDC)。
CLDC是为使用较小的存储容量的设备设计的(参见图3)。
CLDC用于内存在128到512K之间的消费电子设备,这一类别中典型代表的设备包含呼叫器、行动电话、PDA和POS终端;而另一方面,CDC用于比PC机小但是具有比512K内存多的设备,这一类设备包括互联网络电视系统、机顶盒、POS系统、汽车导航以及娱乐系统。
一般来说,CDC使小型设备只要具有少量的资源,至少比台式机要少的资源就能进行Java编程,而CLDC使小型设备所拥有的资源只要比一张智能卡多一点就可以进行Java编程了。
图二解释设备覆盖的范围J2ME有两个配置CLDC和CDC,CLDC是为使用较小的存储容量的设备设计的,而CDC用于比PC机小但是具有比512K内存多的设备。
除了在容量大小和能力上对虚拟机规定了必要条件,配置还规定了类应用程序接口要包含常见的java.io、、java.util和java.lang包,配置可能还要包括其他需要的程序包。
CLDC
CLDC起源可以追溯到1999年JavaOne大会上介绍的Sun的第一个袖珍版Java和第一个KVM以及相关的类库,虽然CLDC和所有的配置都满足成为虚拟机的条件,可它本身还不是虚拟机,CLDC的引用实现只是包含在当前的分布中的KVM。
根据规范中所说,运行CLDC的设备应该有512K或更少的内存空间、一个有限的电源供给(通常是使用电池)、有限的或断断续续的网络连接性(9600bps或更少)以及多样化的用户界面甚至没有用户界面。
通常说来,这个配置是为个人化的、移动的、有限连接信息设备而设计,比如呼叫器、移动电话和PDA等。
与J2SE相比,CLDC缺少下列所说的这些特征:
AWT(抽象窗口开发包),Swing或其他图形库
用户定义类装载器
类实例的最终化
弱的引用
RMI
Reflection(映射)
CLDC有四个包:
java.lang、java.util、java.io和javax.microedition。
除了microedition包以外,其他的这几个包都是J2SE包的核心子集,CLDC采用这些J2SE类库,但是把其中一些在微型设备中用不到类、属性、方法去掉了。
因此CLDC类库有许多细微的差别。
如果您想研究J2SE和CLDC类库之间的差别,请参阅相关文档,在此就不详细说明了。
想要理解为什么CLDC去除这么多J2SE中重要的类和特征,请回想一下与CLDC相关的两条基本原理。
首先,它只有512K的内存空间,而像RMI和映射需要的内存太大了。
其次,配置必须满足为一组通用设备提供最小的Java平台。
在个人移动信息设备领域中,许多系统都不能支持J2SE中的众多的高级特征。
例如,许多消费电子产品不能支持浮点数;因此Float(浮点类)和Double(双精度类)就被删除了。
再看另外一个例子,许多系统没有或不提供访问一个文件系统的功能或权限。
因此与文件有关的类也被丢弃了。
又如,错误处理是一个代价非常高的过程处理,在许多消费电子设备中,故障恢复是很难的甚至是不可能的。
所以在CLDC中,许多错误处理类也被删除了。
java.microedition程序包提供了一个一般的结构来替代许多J2SE网络输入/输出类。
CLDC一般连接器结构还定义了一个Connector类,允许许多不同类型的连接能够使用静态方法,下表列出使用同一个Connector类创建和打开五种不同类型的连接的方法:
HTTPConnector.open("");
套接字Connector.open("socket:
//111.222.111.222:
9000");
通讯端口Connector.open("comm:
1;baudrate=9600");
数据报Connector.open("datagram:
//111.222.111.222");
文件Connector.open("file:
/xyz.dat");
一般连接器结构提供给应用程序开发者一个到通用低水平硬件的简单的映射表。
成功执行open语句将返回一个实现一般连接界面的对象。
CDC
CDC涵盖了个人电脑与有至少512K内存的小型设备之间的中间地带。
现在,这一类设备通常是共享的、固定的(不用移动)网络连接信息设备,像电视机机顶盒,网络电视系统、互联网电话与汽车导航/娱乐系统等等。
首先,CDC基于J2SE1.3应用程序接口,包含所有定义在CLDC规范(包括javax.microedition程序包)中的Java语言应用程序接口。
与CLDC相比,CLDC所有缺少的特性和类在CDC中都被补齐,包含映射、最终化、所有的错误处理类、浮点数、属性、输入/输出(File、FileInputStream等等)和弱的引用。
一般说来,CDC中预期的类包括一个J2SE子集和一个完整的CLDC超集,如图4中所示:
图4:
J2SE、CLDC和CDC的关系
就像使用所有的配置一样,CDC有基层虚拟机的具体的必要条件。
根据CDC规范,基层虚拟机必须提供实现完整的Java虚拟机的支持。
如果虚拟机实现有一个用于激活设备的本地方法的界面,它必须兼容JNI1.1版本。
如果虚拟机实现有一个调试界面,它必须兼容Java虚拟机调试界面(JVMDI)规范。
如果虚拟机有一个简表界面,它必须兼容Java虚拟机简表界面(JVMPI)规范。
可见,为了实现这些功能,CDC肯定会变得很大,就不能称其为K虚拟机了,因此,我们通常称用于CDC的虚拟机为CVM,这里的C代表compact、connected、consumer。
第四节谈谈J2ME简表
虽然配置为一组通用设备提供了最小的Java平台,但是应用程序开发者感兴趣的是为一个个别的设备生产应用程序,当他们只是使用配置的话,他们编写的应用程序就会有一些欠缺。
配置必须满足所有的设备的最小的要求,用户界面、输入机制和数据持久性有高度地设备具体性,每一种设备都有自己的用户界面、输入机制和数据存储方法,这些往往不在配置所满足的最小要求的范围之内。
简表为相同消费电子设备的不同的生产商提供了标准化的Java类库,事实上,虽然配置规范的开发由Sun领导,但是许多简表规范仍将继续由特殊设备的供应商领导。
比如说,Motorola领导了行动电话和呼叫器简表规范的开发,又如Palm领导PDA简表的开发。
现在,五个已知简表已经有了规范,记住,每个简表的责任都是为了完善配置的不足,下表列出了这五个简表:
简表
完善配置
Mobileinformationdevicesprofile(MIDP)
移动电话和呼叫器CLDC
Personaldigitalassistantprofile
Palm和Handspring的PDA设备CLDC
Foundationprofile
用于所有不需要GUI的CDC设备的标准简表CDC
Personalprofile
替代PersonalJava的Foundation完善的简表CDC
RMIprofile
提供RMI的Foundation完善的简表CDC
现在我想谈一谈另一个Java类库集,它现在差不多可以被认为是另一个简表了。
当Sun为Palm开发第一个KVM时,他们需要一组类来开发Palm的演示程序。
这套类库被封装进com.sun.kjava程序包,在CLDC早期的开发中,这些类被广泛的使用来测试和演示J2ME。
因为kjava是唯一的允许应用程序开发者使用J2ME和KVM开发应用程序的类,所以它就被广泛使用了。
甚至到了今天,一个用于PDA或更特殊一点的Palm的简表多已经在开发中,许多开发者仍然希望使用kjava类来开发PDA应用程序。
尽管kjava类不被支持,并且仅仅用于设计测试程序或演示程序,并且它们将被一个即将到来的简表所替代,但是开发者们仍然热衷于使用它来开发。
MIDP
MobileInformationDeviceProfile(移动信息设备简表,简称MIDP),第一个实现的简表,补充了CLDC并且提供应用程序语义和控件、用户界面、持久存储器、网络和用于移动电话的计时器、双通道呼叫器和其他无线电设备。
因为MIDP和CLDC两者都有引用实现,我们可以使用一个例程来研究一下这个简表。
下面的例子是一个允许用户输入代表想知道的基金报价的代号的例子。
应用程序然后通过HTTP接到一个金融网站,获得基金报价,把价格储存在一个数据库,然后把价格返回给用户。
//到如需要的J2ME类
importjavax.microedition.midlet.*;
importjavax.microedition.lcdui.*;
importjavax.microedition.rms.*;
//扩展MIDlet类来构建我们的自定义MIDlet
publicclassFundTrackerextendsMIDletimplements
CommandListener{
file:
//显示管理者变量
privateDisplaydisplay=null;
file:
//MIDlet的表单变量
privateRequestFormreqForm=null;
file:
//MIDlet构建器
publicFundTracker(){
display=Display.getDisplay(this);
reqForm=newRequestForm("FundTracker");
reqForm.initForm();
reqForm.setCommandListener(this);
}
file:
//开始MIDlet应用程序
protectedvoidstartApp(){
display.setCurrent(reqForm);
}
file:
//暂停Midlet
protectedvoidpauseApp(){
}
file:
//销毁Midlet
protectedvoiddestroyApp(booleanunconditional){
}
file:
//通过监听者响应命令
publicvoidcommandAction(Commandc,Displayables){
if(c==reqForm.getExitCommand()){
destroyApp(false);
notifyDestroyed();
return;
}
if((c==reqForm.getGetCommand())&&
(reqForm.getSymField().getString().length()>0)){
getAndDisplayQuote();
}else
{
reqForm.getMsgString().setText("Symbolrequired");
}
}
file:
//储存由#分开的成对的基金字符串和报价字符串
privatevoidstoreQuote(Stringfund,StringnewQuote){
file:
//数据库变量
RecordStorequoteDB=null;
try{
quoteDB=RecordStore.openRecordStore(
"FundQuotes",true);
byte[]data=(fund+"#"+newQuote).getBytes();
intsize=data.length;
quoteDB.addRecord(data,0,size);
quoteDB.closeRecordStore();
}
catch(ExceptionrecordException){
System.out.println("Unabletostorequoteand/or
useFundQuotedatabase.");
}
}
file:
//通过QuoteService类取回提交的代号表示的基金报价
privatevoidgetAndDisplayQuote(){
StringfundSymbol=reqForm.getSymField().getString();
if(fundSymbol.length()>0){
StringtheQuote=QuoteService.getQuote(fundSymbol);
if(theQuote!
=null){
storeQuote(fundSymbol,theQuote);
reqForm.getMsgString().setText(theQuote);
}
else
reqForm.getMsgString().setText("Noquote"+
'\n'+"CheckSymbol");
}
}
}
MIDP应用程序称为MIDlet,为了创建一个MIDlet,你必须写一个扩展基本MIDlet类的类(就像我们在上面代码段中列出的那样)。
这有点类似常见的applet或servlet。
MIDlets独有的东西是把多个MIDlet组成一个MIDlet套件的能力。
这就允许MIDlet在一个单独的JVM环境中共享资源,比如一个数据库等等。
事实上,我们上面给出的例子还包括一个MIDlet(RetrieveQuote,见上段程序),用于取回所报价格。
当MIDlet被请求时,MIDlet通过构造程序实例化,然后调用实例的startApp()方法。
在FundTracker例子中,MIDlet的用户界面或显示是由Display类的一个实例管理的。
对于每个MIDlet,只有一个显示管理器实例。
所有可以显示的项目,像屏幕或画布(canvas),通过这个管理器都能够成为可见的。
因为行动电话和呼叫器能力的多样化,又因为用于这些设备的应用程序类型的差异,MIDP规范提供了两种类型的用户界面。
一个可移植性稍差、明确设备、低水平的应用程序接口,允许图形元素精确的控制和放置。
这个接口类型是用于应用程序特性比较典型的设备特别设计的,比如电子游戏。
一个可移植性稍好的、抽象的、高级的GUI应用程序接口,提供来用于商业应用程序。
我们的例程使用的是高级的应用程序接口和典型的用户界面组件(文本框,列表等等),是这类界面通用的。
比如说,实际的表单和所有的小组件在一个单独的文件中都已定义。
就像在代码段一中列出的那样,当MIDlet创建时,一个表单的实例与MIDlet关联。
在调用MIDletstartApp()方法的时候,通过Display对象显示表单。
使用一个用于表单的类,允许我们在我们简单的报价检索应用程序中重新使用这个表单(RetrieveQuote)。
为了清晰性和风格,我们通过一个单