做J2ME应用开发的程序员也许经常会被一些名词或者概念所迷惑,比如Personal Basic Profile和Personal Profile有什么关系?基于CLDC的应用程序能够无修改的移植到基于CDC的设备上嘛?要回答这些问题并不容易,因为你必须首先揭开J2ME平台的神秘面纱。
2000年当J2ME平台的CLDC发布的时候,所有的java开发者都为之兴奋不已。SUN也不负众望在两个月后发布了基于CLDC的MIDP,给开发者提供了开发交互式应用程序的平台。我想现在国内还主要是基于CLDC/MIDP在开发应用吧。J2ME平台的另一个规范CDC在大概10个月后才发布,同时发布的还有Foundation Profile。但是由于他们都没有给开发者提供开发可交互应用程序的API,因此他们发布的影响远远小于CLDC/MIDP的发布。大概在2003年SUN发布了基于CDC的Personal Basic Profile和Personal Profile。他们的组合替代了以前的PersonalJava平台。
是不是已经被这些名字弄糊涂了,我们现在来看J2ME平台的结构。J2ME平台是本着Configuration和Profile结合来设计的。Configuration是提供支持最大范围设备的最小的平台。Profile是针对特定的设备提供相应的开发包集合。在J2ME的两个基本配置CDC和CLDC是按照如下的标准进行区分的。
CLDC:
512 KB 以下内存
有限能源供应(通常使用电池)
有限或非持续网络连接
简单的用户界面
16位或者32位的处理器
CDC:
2M以上内存
具有网络连接能力,通常为无线网络
需要实现java虚拟机规范的全部功能
32位或者64位的处理器
从上述的要求中我们不难看出CLDC主要针对那些资源非常受限的设备比如手机、PDA、双工寻呼机等。而CDC主要面对那些家电产品,比如机顶盒、汽车导航系统等。
下面我们来看看J2ME平台的结构图:

我们可以看出J2ME的核心是Configuration,在它里面定义了java的虚拟机,通过它来和底层的Host OS打交道。Profile提供了访问设备的IO或者图形界面的能力,这样Configuration和Profile共同构成了J2ME的运行环境。比如CLCD/MIDP可以提供给你开发手机程序的环境。在Profile之上针对不同的设备还可以提供不同的可选开发包。
由于CLDC/MIDP大家都比较熟悉了,我们下面主要介绍一下基于CDC的J2ME系统构架,同样还是看它的系统图:

基于CDC的设备可以支持全部的Java2语言规范和Java虚拟机规范,它是CLDC的超集并且远大于CLDC,因此基于CLDC的程序是可以无修改的移植到基于CDC的设备的。Foundation Profile是对CDC进行扩展的Profile,但是他并没有提供GUI的开发包,GUI是在Personal Basic Profile中进行定义的,它提供了AWT的一个子集给开发人员。它还提供了Xlet应用程序模式——针对java TV。Personal Profile是Personal Basci Profile的超集。他提供了对Applet的支持,丰富了AWT的组件,添加了java.awt.datatransfer包。
总结:上面是我对J2ME平台进行的阐述,我想最重要的就是Configuration/Profile的设计。理解了它就掌握了一半。如果大家有不同的意见,欢迎一起交流!
1 CLDC包含的功能
在CLDC1.0版本中定义了以下功能:
1)Java核心语言与Java虚拟机的特性
2)核心Java类库
3)输入/输出
4)对网络的支持
5)对安全性的支持
6)对国际化的支持
2 CLDC不包含的功能
1)对应用程序生命周期的管理
2)用户界面
3)事件处理
4)高级应用程序模式(这里指用户与应用程序的交互)
3 CLDC与J2SE的关系
CLDC包含了一个基本的J2ME运行环境,其中包括虚拟机和核心的java类库。作为专门针对于小型设备的配置,CLDC对J2SE类库进行了大量的简化,其类库只保留了java 规范中定义的最核心的3个包,即java.iojava.lang和java.util,并重新定义了一个新的包javax.microedition。这里你可以通过前缀来区别:java.表示核心的java包,javax.表示标准java扩展包。
这里要注意的是在CLDC中定义的javax.microedition包为javax.microedition.io,用来支持通用连接框架(GCF,Generic connection framework)。CLDC中的包和所对应的功能如下所示:
| CLDC包 |
对应的功能 |
| java.io |
标准的输入/输出功能,J2SE java.io包的子集 |
| java.lang |
核心语言包,J2SE的子集 |
| java.util |
实用类 |
| javax.microedition.io |
通用连接框架类及接口 |
javax.microedition中其他的包定义了CLDC中没有定义的功能,如对应用程序生命周期的管理、用户界面(UI)、事件处理模式、永久性存储和用户与应用程序的交互等。这些功能的定义是由Profile (即MIDP)来完成的。
4 CLDC核心类库与J2SE的主要区别
由于CLDC主要针对16位、32位主频在16MHz以上的处理器,设备内存只有512KB,甚至更少,而目前Windows平台下运行的JVM需要的最小内存为16M。因此CLDC所使用的虚拟机和核心类库与J2SE的并不相同。
1.不支持浮点数据类型(没有float和double)
因为很多使用CLDC的设备硬件都不支持浮点运算,而且处理浮点运算需要较大的内存。因此在CLDC1.0中,并没有要求虚拟机支持浮点数据类型。
|
9) dadd
|
10) dmul
|
11) fadd
|
12) fmul
|
13) i2d
|
|
14) dalaod
|
15) dneg
|
16) faload
|
17) fneg
|
18) i2f
|
|
19) dastore
|
20) drem
|
21) fastore
|
22) frem
|
23) l2d
|
|
24) dcmpg
|
25) dreturn
|
26) fcmpg
|
27) freturn
|
28) l2f
|
|
29) dcmpl
|
30) dstore
|
31) fcmpl
|
32) fstore
|
33) newarray(double)
|
|
34) dconst_0
|
35) dstore_x
|
36) fconst_0
|
37) fstore_x
|
38) newarray(float)
|
|
39) dconst_1
|
40) dsub
|
41) fconst_1
|
42) fsub
|
43)
|
|
44) ddiv
|
45) d2f
|
46) fdiv
|
47) f2f
|
48)
|
|
49) dload
|
50) d2i
|
51) fload
|
52) f2i
|
53)
|
|
54) dload_x
|
55) d2l
|
56) fload_x
|
57) f2l
|
58)
|
CLDC不支持的浮点数据类型
对于CLDC的应用,Sun使用了和J2SE相同的编译器,这使得使用浮点数据的类及对象在编译的时候可以正常通过。因此Sun引入了类审核机制来阻止未经定义的类调入虚拟机。
2.不支持JNI (the Java Native Interface )
CLDC不提供native code的支持,除了因为设备内存有限外,还出于安全性的考虑。因为CLDC中缺少完整的安全性模型,禁用了这些J2SE的特性可以使潜在的安全风险降到最低。
3.不支持以及用户自定义的Java级的类载入器(class loaders)
CLDC不允许用户自定义类载入器。按照CLDC规范的要求,类的载入是不能被覆盖、替换和修改的。和JNI类似,这些是出于安全方面的一些考虑。
4.不支持反射(reflection)
不支持java.lang.reflect包以及java.lang.Class中和reflection有关的函数。其目的主要是节省内存占用。
5.不支持线程组(thread groups)或守护线程(daemon threads)
CLDC提供了对线程的支持,也支持多线程,但是线程组和守护线程是不被允许的。每个线程都要生成独立的Thread对象来实现。如果应用程序想实现对一组线程的操作,则必须在应用程序的级别上自行实现多个Thread对象的控制,如使用Hashtable和Vector来存取多个Thread对
6.不支持类实例(class instance)的终结(finalization)
CLDC类库不包含java.lang.Object.finalize()方法,因此类对象的终结是不支持的。对于应用CLDC的设备来说,对象终结相对于它所起的作用来说实现起来过于复杂,并不被需要
7.不支持弱引用(weak references
8.有限的错误处理(error handling)
在J2SE中定义了大量的类用来描述各种错误和异常,而CLDC仅仅包含有限的几个J2SE的核心类库,因此大部分java.lang.Error的子类都未被支持,这包括异步异常。这是因为在嵌入式系统中,应用程序并不期望获得设备的出错处理机制;定义和运行出错处理需要较大的虚拟机的开销,而这些出错的代码信息对于连用户界面都没有的有限连接设备来说是没有用处的。