一、J2ME概述
到目前為止,大部分人都已非常熟悉 Java 2平臺(tái),以及 Sun如何把 Java技術(shù)分成三個(gè)版本 (標(biāo)準(zhǔn)版、袖珍版以及企業(yè)版),Sun 在1999年6月時(shí)推出了 Java 2袖珍版 (J2ME)來(lái)滿足消費(fèi)電子和嵌入設(shè)備的需要。J2ME是為了那些使用有限的能源、有限的網(wǎng)絡(luò)連接 (常常是無(wú)線連接)以及有限圖形用戶界面能力的設(shè)備開(kāi)發(fā)的。它初的目標(biāo)是 16位或 32位處理器,16 MHz時(shí)鐘頻率, 512K或更少內(nèi)存的設(shè)備。乍一看之下, J2ME就像一個(gè)沒(méi)有綁定明顯主題的松散的應(yīng)用程序接口和技術(shù)規(guī)范。我們想通過(guò)說(shuō)它不是什么東西的方法來(lái)描述它,它不是一組用于臺(tái)式機(jī) Java應(yīng)用程序規(guī)范,如果你再觀察仔細(xì)一些,你會(huì)發(fā)現(xiàn)所有的 J2ME組件都圍繞一個(gè)中心,這些中心被稱為configuration(配置 ,Sun的市場(chǎng)營(yíng)銷(xiāo)資料也稱它們 design centers,設(shè)計(jì)中心),它們中間的每一個(gè)都是用于消費(fèi)電子和嵌入設(shè)備的特別的類(lèi)。
Connected limited device configuration(有限連接設(shè)備配置,簡(jiǎn)稱 CLDC ) 這個(gè)配置定義了 Java應(yīng)用程序接口以及支持手持設(shè)備的技術(shù),就像 Sun的文檔中所描述的那樣, " devices that you hold in your hand(你握在手中的設(shè)備) " Palm序列手持設(shè)備可能是這一領(lǐng)域的設(shè)備的的例子,特別是它有開(kāi)發(fā) CLDC的功能以及 Palm設(shè)備運(yùn)行期系統(tǒng)可用。
Connected device configuration(連接設(shè)備配置 CDC ) 這個(gè)配置定義支持象 Sun文檔中所說(shuō), " devices that you plug into plug into the wall(你插入墻的設(shè)備)的設(shè)備的應(yīng)用程序接口和技術(shù),這樣的設(shè)備的一個(gè)例子可能就是機(jī)頂盒。
這兩種配置不同的地方就在于它們應(yīng)用于的裝置的能力, CLDC設(shè)備的處理器能力有限 (與臺(tái)式機(jī)系統(tǒng)比較 ),并且存儲(chǔ)器大小一般也只在128 KB到 512 KB之間, 與此同時(shí),CDC系統(tǒng)就不同了,它可能有 32位或 64位處理器,以及有限的存儲(chǔ)容量,不過(guò)它的下限也得超過(guò)512K。 它遵循的原則就是,每個(gè)不同的能力硬件的配置都將被不同的虛擬機(jī)支持。 基于 CDC的系統(tǒng)使用一個(gè)功能強(qiáng)勁的虛擬機(jī),而基于 CLDC系統(tǒng)的使用 KVM 。
每個(gè)配置代表一種低水平的,基本的應(yīng)用程序接口,在這兩個(gè)相似基礎(chǔ)之上是 profile(簡(jiǎn)表),用于特殊設(shè)備的額外的應(yīng)用程序接口。 我想通過(guò)看一張來(lái)自SUN提供的文檔中的圖表 (參見(jiàn)圖 1 )來(lái)解釋這其中的關(guān)系。
J2ME的體系結(jié)構(gòu)被橫向地分成三層,縱向分成兩部分。配置包括一個(gè)控制配置核心類(lèi)的虛擬機(jī), 具體的簡(jiǎn)表位于每個(gè)配置之上。
J2ME現(xiàn)在定義兩個(gè)配置, Connected Device configuration(連接設(shè)備配置 CDC )和限制性更強(qiáng)的 Connected Limited Device Configuration (有限連接設(shè)備配置)。 簡(jiǎn)表的實(shí)現(xiàn)是 Java應(yīng)用程序接口的一個(gè)集合,用于適應(yīng)被定義配置的應(yīng)用程序接口提供的服務(wù),簡(jiǎn)表是一個(gè)完整的運(yùn)行環(huán)境,一個(gè)在簡(jiǎn)表上執(zhí)行的應(yīng)用程序不需要額外的支持類(lèi)。
J2ME沒(méi)有定義滿足這兩種配置的標(biāo)準(zhǔn)化用戶接口,Sun也承認(rèn)現(xiàn)在的消費(fèi)設(shè)備多種多樣,用戶界面也各不一樣,所以定義一個(gè)可用于所有用戶的界面是一場(chǎng)失敗的戰(zhàn)爭(zhēng)。 J2ME中的用戶界面定義在簡(jiǎn)表中。
二、J2ME的體系結(jié)構(gòu)
現(xiàn)在個(gè)人計(jì)算機(jī)系統(tǒng)的數(shù)量和種類(lèi)已經(jīng)發(fā)展到無(wú)法控制的地步,請(qǐng)你想一想,你編寫(xiě)的程序運(yùn)行在“信息家電”舞臺(tái)的情景吧,這些信息家電包括呼叫器,行動(dòng)電話,像Palm這樣的個(gè)人數(shù)字助手(PDA),電視機(jī)頂盒,POS終端以及其他的消費(fèi)電子設(shè)備。現(xiàn)在全世界上光是手提電話生產(chǎn)商就有許多,更不用說(shuō)別的家電設(shè)備了,而且每一種家電設(shè)備又有不同的特性和界面。所以,你可以想到, Java應(yīng)用程序的輕便性以及能夠解決開(kāi)發(fā)這么許多不同的設(shè)備程序的能力,使大家對(duì)J2ME有很大的期許。當(dāng)然,為了更好的開(kāi)發(fā)這些信息家電,就要求把Java的精髓壓縮進(jìn)一個(gè)非常小的程序包中,這就是J2ME。
J2ME是一種通過(guò)許多部件和規(guī)范的技術(shù), 這眾多的部件和規(guī)范幫助 J2ME來(lái)滿足這眾多的消費(fèi)產(chǎn)品的不同的需要。和所有的爪哇程式語(yǔ)言技術(shù)一樣,在它的核心屬于一種虛擬機(jī)。 就像使用所有 Java技術(shù)一樣,J2ME的核心也在一種虛擬機(jī)中。 初,用于 J2ME應(yīng)用程序虛擬機(jī)的被稱作 Kilobyte virtual machine或簡(jiǎn)稱 KVM。就像它名稱的含義, KVM比較小,通常只有 128K或更少。這比起我們通常了解和使用的 Java 2標(biāo)準(zhǔn)版 Java虛擬機(jī) ( JVM )的 32 MB來(lái)說(shuō)就小得多了。
用于連接虛擬機(jī)的是一系列配置和簡(jiǎn)表,它們提供了用于特定 J2ME環(huán)境的類(lèi)應(yīng)用程序接口(見(jiàn)圖二)。 每個(gè)配置和簡(jiǎn)表處理一般或具體的消費(fèi)產(chǎn)品,配置和簡(jiǎn)表規(guī)范是由多種多樣的設(shè)備生產(chǎn)商和用戶共同開(kāi)發(fā)并建立的。配置是用于一組通用設(shè)備的小的 Java平臺(tái), 常常歸為一種橫向的設(shè)備分組,相對(duì)來(lái)說(shuō),橫向分組設(shè)備是那些共享相同的內(nèi)存安排,通信帶寬,能量需求以及用戶能力的設(shè)備,一般認(rèn)為配置能夠提供這眾多的設(shè)備的所有需求。
Java虛擬機(jī)是 J2ME技術(shù)的核心,但是配置和簡(jiǎn)表提供特殊環(huán)境的類(lèi)應(yīng)用程序接口。配置是用于一組通用設(shè)備的小的 Java平臺(tái),而簡(jiǎn)表則為具體的設(shè)備家族或特別的應(yīng)用程序提供更具體的能力。
J2ME領(lǐng)域的新的開(kāi)發(fā)者常常被這些事實(shí)困惑的, 事實(shí)上, Sun的個(gè)配置(現(xiàn)在只是一種配置的引用實(shí)現(xiàn) )帶有稱為 KVM的虛擬機(jī)引用實(shí)現(xiàn), KVM滿足配置的虛擬機(jī)的必要條件。然而, Sun的 KVM也可以被另外一個(gè)虛擬機(jī)所代替,現(xiàn)在, 正是因?yàn)榕渲煤吞摂M機(jī)結(jié)合得有點(diǎn)緊密,因此導(dǎo)致了這么多的混亂。
另一方面,簡(jiǎn)表完善了 配置,為某個(gè)具體的設(shè)備家族或某個(gè)具體的工業(yè)片段應(yīng)用程序提供更高的性能。 換言之, 簡(jiǎn)表為具體的縱向市場(chǎng)的設(shè)備比如說(shuō)行動(dòng)電話提供更多的性能。這里的關(guān)鍵就是 簡(jiǎn)表必須完善 配置, 沒(méi)有 配置和虛擬機(jī)提供核心類(lèi)應(yīng)用程序接口和運(yùn)行期環(huán)境的話,簡(jiǎn)表也不會(huì)工作。
通常,簡(jiǎn)表為一種給定的垂直分組設(shè)備提供用戶界面、輸入法、持久性機(jī)制。這類(lèi) 簡(jiǎn)表被認(rèn)為是發(fā)展這些設(shè)備應(yīng)用程序的完整的工具包。我們見(jiàn)到多的應(yīng)用程序簡(jiǎn)表的例子就移動(dòng)電話簡(jiǎn)表和個(gè)人數(shù)字助手(PDA)簡(jiǎn)表,其他簡(jiǎn)表為范圍寬廣的設(shè)備提供非常特殊的功能或應(yīng)用程序可移植性,這方面的例子就是提供遠(yuǎn)程方法調(diào)用 ( RMI )功能的簡(jiǎn)表和提供統(tǒng)一銀行事務(wù)的簡(jiǎn)表。
虛擬機(jī)、 配置、 簡(jiǎn)表…你是不是已經(jīng)被搞迷糊了? 如果這樣的話,我們就來(lái)簡(jiǎn)化一下 J2ME體系結(jié)構(gòu)吧。 如果你想為小型信息家電編寫(xiě) Java應(yīng)用程序的話,你就需要兩個(gè)前提:一個(gè) 配置和至少一個(gè) 簡(jiǎn)表。 現(xiàn)在, 一般是配置捆綁了虛擬機(jī)和一套針對(duì)你的平臺(tái)所能夠用的橫向分組設(shè)備的Java類(lèi)庫(kù)。其次,你至少還需要一個(gè) 簡(jiǎn)表來(lái)為你的平臺(tái)提供附加的 Java類(lèi),這個(gè) 簡(jiǎn)表通常會(huì)為你的設(shè)備提供用戶界面、輸入和數(shù)據(jù)庫(kù)類(lèi)。有了這兩個(gè)前提,你就了使用 Java為你的設(shè)備編寫(xiě)應(yīng)用程序的基本的J2ME環(huán)境。
三、詳細(xì)談?wù)凧2ME配置
J2ME可以在好幾個(gè)不同的配置中進(jìn)行配置。就像先前提到的,每個(gè)配置為一組通用設(shè)備提供小的 Java平臺(tái),到目前為止,只有兩種配置規(guī)范。通過(guò) Java規(guī)范定義的這兩種配置是 Connected Limited Device Configuration (有限連接設(shè)備配置, CLDC )和 Connected Device Configuration (連接設(shè)備配置 CDC )。
CLDC是為使用較小的存儲(chǔ)容量的設(shè)備設(shè)計(jì)的 (參見(jiàn)圖3 )。 CLDC用于內(nèi)存在128到 512K之間的消費(fèi)電子設(shè)備, 這一類(lèi)別中典型代表的設(shè)備包含呼叫器、行動(dòng)電話、PDA和POS終端;而另一方面, CDC用于比 PC機(jī)小但是具有比 512K內(nèi)存多的設(shè)備,這一類(lèi)設(shè)備包括互聯(lián)網(wǎng)絡(luò)電視系統(tǒng)、機(jī)頂盒、POS系統(tǒng)、汽車(chē)導(dǎo)航以及娛樂(lè)系統(tǒng)。一般來(lái)說(shuō), CDC使小型設(shè)備只要具有少量的資源,至少比臺(tái)式機(jī)要少的資源就能進(jìn)行Java編程,而CLDC使小型設(shè)備所擁有的資源只要比一張智能卡多一點(diǎn)就可以進(jìn)行Java編程了。
J2ME有兩個(gè)配置CLDC和 CDC,CLDC是為使用較小的存儲(chǔ)容量的設(shè)備設(shè)計(jì)的,而CDC用于比 PC機(jī)小但是具有比 512K內(nèi)存多的設(shè)備。
除了在容量大小和能力上對(duì)虛擬機(jī)規(guī)定了必要條件,配置還規(guī)定了類(lèi)應(yīng)用程序接口要包含常見(jiàn)的 java.io、 java.net、 java.util和 java.lang包,配置可能還要包括其他需要的程序包。
CLDC
CLDC起源可以追溯到1999年JavaOne大會(huì)上介紹的Sun的個(gè)袖珍版 Java和個(gè) KVM以及相關(guān)的類(lèi)庫(kù),雖然 CLDC和所有的配置都滿足成為虛擬機(jī)的條件,可它本身還不是虛擬機(jī),CLDC的引用實(shí)現(xiàn)只是包含在當(dāng)前的分布中的 KVM。
根據(jù)規(guī)范中所說(shuō),運(yùn)行 CLDC的設(shè)備應(yīng)該有 512K或更少的內(nèi)存空間、一個(gè)有限的電源供給 (通常是使用電池)、有限的或斷斷續(xù)續(xù)的網(wǎng)絡(luò)連接性 ( 9600 bps或更少 )以及多樣化的用戶界面甚至沒(méi)有用戶界面。 通常說(shuō)來(lái),這個(gè)配置是為個(gè)人化的、移動(dòng)的、有限連接信息設(shè)備而設(shè)計(jì),比如呼叫器、移動(dòng)電話和 PDA等。
與 J2SE相比, CLDC缺少下列所說(shuō)的這些特征:
AWT(抽象窗口開(kāi)發(fā)包), Swing或其他圖形庫(kù)
用戶定義類(lèi)裝載器
類(lèi)實(shí)例的終化
弱的引用
RMI
Reflection(映射)
CLDC有四個(gè)包: java.lang、 java.util、 java.io和 javax.microedition。 除了 microedition包以外,其他的這幾個(gè)包都是J2SE包的核心子集,CLDC采用這些J2SE類(lèi)庫(kù),但是把其中一些在微型設(shè)備中用不到類(lèi)、屬性、方法去掉了。因此 CLDC類(lèi)庫(kù)有許多細(xì)微的差別。 如果您想研究J2SE和 CLDC類(lèi)庫(kù)之間的差別,請(qǐng)參閱相關(guān)文檔,在此就不詳細(xì)說(shuō)明了。
想要理解為什么CLDC去除這么多J2SE中重要的類(lèi)和特征,請(qǐng)回想一下與 CLDC相關(guān)的兩條基本原理。首先,它只有 512K的內(nèi)存空間, 而像RMI和映射需要的內(nèi)存太大了。 其次,配置必須滿足為一組通用設(shè)備提供小的 Java平臺(tái)。 在個(gè)人移動(dòng)信息設(shè)備領(lǐng)域中,許多系統(tǒng)都不能支持 J2SE中的眾多的特征。 例如,許多消費(fèi)電子產(chǎn)品不能支持浮點(diǎn)數(shù); 因此 Float(浮點(diǎn)類(lèi))和 Double(雙精度類(lèi))就被刪除了。 再看另外一個(gè)例子,許多系統(tǒng)沒(méi)有或不提供訪問(wèn)一個(gè)文件系統(tǒng)的功能或權(quán)限。 因此與文件有關(guān)的類(lèi)也被丟棄了。又如,錯(cuò)誤處理是一個(gè)代價(jià)非常高的過(guò)程處理,在許多消費(fèi)電子設(shè)備中,故障恢復(fù)是很難的甚至是不可能的。 所以在 CLDC中,許多錯(cuò)誤處理類(lèi)也被刪除了。
java.microedition程序包提供了一個(gè)一般的結(jié)構(gòu)來(lái)替代許多 J2SE網(wǎng)絡(luò)輸入/輸出類(lèi)。 CLDC一般連接器結(jié)構(gòu)還定義了一個(gè) Connector類(lèi),允許許多不同類(lèi)型的連接能夠使用靜態(tài)方法,下表列出使用同一個(gè)Connector類(lèi)創(chuàng)建和打開(kāi)五種不同類(lèi)型的連接的方法:
HTTP Connector.open("http://www.xyz.com");
套接字 Connector.open("socket://111.222.111.222:9000");
通訊端口 Connector.open("comm:1;baudrate=9600");
數(shù)據(jù)報(bào) Connector.open("datagram://111.222.111.222");
文件 Connector.open("file:/xyz.dat");
一般連接器結(jié)構(gòu)提供給應(yīng)用程序開(kāi)發(fā)者一個(gè)到通用低水平硬件的簡(jiǎn)單的映射表。成功執(zhí)行 open語(yǔ)句將返回一個(gè)實(shí)現(xiàn)一般連接界面的對(duì)象。
CDC
CDC涵蓋了個(gè)人電腦與有至少 512K內(nèi)存的小型設(shè)備之間的中間地帶。現(xiàn)在,這一類(lèi)設(shè)備通常是共享的、固定的 (不用移動(dòng))網(wǎng)絡(luò)連接信息設(shè)備,像電視機(jī)機(jī)頂盒,網(wǎng)絡(luò)電視系統(tǒng)、互聯(lián)網(wǎng)電話與汽車(chē)導(dǎo)航/娛樂(lè)系統(tǒng)等等。
首先,CDC基于 J2SE 1.3應(yīng)用程序接口,包含所有定義在CLDC規(guī)范(包括 javax.microedition程序包)中的Java語(yǔ)言應(yīng)用程序接口。與CLDC相比, CLDC所有缺少的特性和類(lèi)在 CDC中都被補(bǔ)齊,包含映射、終化、所有的錯(cuò)誤處理類(lèi)、浮點(diǎn)數(shù)、屬性、輸入/輸出 ( File、 FileInputStream等等 )和弱的引用。 一般說(shuō)來(lái), CDC中預(yù)期的類(lèi)包括一個(gè)J2SE子集和一個(gè)完整的 CLDC超集,如圖4中所示:
就像使用所有的配置一樣,CDC有基層虛擬機(jī)的具體的必要條件。 根據(jù) CDC規(guī)范,基層虛擬機(jī)必須提供實(shí)現(xiàn)完整的 Java虛擬機(jī)的支持 。 如果虛擬機(jī)實(shí)現(xiàn)有一個(gè)用于激活設(shè)備的本地方法的界面,它必須兼容 JNI 1.1版本。 如果虛擬機(jī)實(shí)現(xiàn)有一個(gè)調(diào)試界面,它必須兼容 Java虛擬機(jī)調(diào)試界面 ( JVMDI )規(guī)范。 如果虛擬機(jī)有一個(gè)簡(jiǎn)表界面,它必須兼容 Java虛擬機(jī)簡(jiǎn)表界面 ( JVMPI )規(guī)范。 可見(jiàn),為了實(shí)現(xiàn)這些功能,CDC肯定會(huì)變得很大,就不能稱其為K虛擬機(jī)了,因此,我們通常稱用于CDC的虛擬機(jī)為 CVM,這里的 C代表 compact、connected、consumer。
四、談?wù)凧2ME簡(jiǎn)表
雖然配置為一組通用設(shè)備提供了小的 Java平臺(tái),但是應(yīng)用程序開(kāi)發(fā)者感興趣的是為一個(gè)個(gè)別的設(shè)備生產(chǎn)應(yīng)用程序,當(dāng)他們只是使用配置的話,他們編寫(xiě)的應(yīng)用程序就會(huì)有一些欠缺。 配置必須滿足所有的設(shè)備的小的要求, 用戶界面、輸入機(jī)制和數(shù)據(jù)持久性有高度地設(shè)備具體性,每一種設(shè)備都有自己的用戶界面、輸入機(jī)制和數(shù)據(jù)存儲(chǔ)方法,這些往往不在配置所滿足的小要求的范圍之內(nèi)。
簡(jiǎn)表為相同消費(fèi)電子設(shè)備的不同的生產(chǎn)商提供了標(biāo)準(zhǔn)化的 Java類(lèi)庫(kù), 事實(shí)上,雖然配置規(guī)范的開(kāi)發(fā)由 Sun領(lǐng)導(dǎo),但是許多簡(jiǎn)表規(guī)范仍將繼續(xù)由特殊設(shè)備的供應(yīng)商領(lǐng)導(dǎo)。 比如說(shuō), Motorola領(lǐng)導(dǎo)了行動(dòng)電話和呼叫器簡(jiǎn)表規(guī)范的開(kāi)發(fā),又如 Palm 領(lǐng)導(dǎo) PDA簡(jiǎn)表的開(kāi)發(fā)。
現(xiàn)在,五個(gè)已知簡(jiǎn)表已經(jīng)有了規(guī)范, 記住,每個(gè)簡(jiǎn)表的責(zé)任都是為了完善配置的不足,下表列出了這五個(gè)簡(jiǎn)表:
簡(jiǎn) 表 完善配置
Mobile information devices profile (MIDP) 移動(dòng)電話和呼叫器 CLDC
Personal digital assistant profile Palm和Handspring的PDA 設(shè)備 CLDC
Foundation profile 用于所有不需要GUI的CDC設(shè)備的標(biāo)準(zhǔn)簡(jiǎn)表 CDC
Personal profile 替代PersonalJava的Foundation完善的簡(jiǎn)表 CDC
RMI profile 提供RMI的Foundation完善的簡(jiǎn)表 CDC
現(xiàn)在我想談一談另一個(gè)Java類(lèi)庫(kù)集,它現(xiàn)在差不多可以被認(rèn)為是另一個(gè)簡(jiǎn)表了。當(dāng)Sun為Palm開(kāi)發(fā)個(gè)KVM時(shí),他們需要一組類(lèi)來(lái) 開(kāi)發(fā)Palm的演示程序。這套類(lèi)庫(kù)被封裝進(jìn) com.sun.kjava程序包, 在 CLDC早期的開(kāi)發(fā)中,這些類(lèi)被廣泛的使用來(lái)測(cè)試和演示 J2ME。因?yàn)?kjava是的允許應(yīng)用程序開(kāi)發(fā)者使用 J2ME和 KVM開(kāi)發(fā)應(yīng)用程序的類(lèi),所以它就被廣泛使用了。甚至到了今天,一個(gè)用于 PDA或更特殊一點(diǎn)的 Palm的簡(jiǎn)表多已經(jīng)在開(kāi)發(fā)中,許多開(kāi)發(fā)者仍然希望使用 kjava類(lèi)來(lái)開(kāi)發(fā) PDA應(yīng)用程序。盡管 kjava類(lèi)不被支持,并且僅僅用于設(shè)計(jì)測(cè)試程序或演示程序,并且它們將被一個(gè)即將到來(lái)的簡(jiǎn)表所替代,但是開(kāi)發(fā)者們?nèi)匀粺嶂杂谑褂盟鼇?lái)開(kāi)發(fā)。
MIDP
Mobile Information Device Profile(移動(dòng)信息設(shè)備簡(jiǎn)表 ,簡(jiǎn)稱 MIDP ),個(gè)實(shí)現(xiàn)的簡(jiǎn)表,補(bǔ)充了 CLDC并且提供應(yīng)用程序語(yǔ)義和控件、用戶界面、持久存儲(chǔ)器、網(wǎng)絡(luò)和用于移動(dòng)電話的計(jì)時(shí)器、雙通道呼叫器和其他無(wú)線電設(shè)備。 因?yàn)?MIDP和 CLDC兩者都有引用實(shí)現(xiàn),我們可以使用一個(gè)例程來(lái)研究一下這個(gè)簡(jiǎn)表。
下面的例子是一個(gè)允許用戶輸入代表想知道的基金報(bào)價(jià)的代號(hào)的例子。應(yīng)用程序然后通過(guò) HTTP接到一個(gè)金融網(wǎng)站,獲得基金報(bào)價(jià),把價(jià)格儲(chǔ)存在一個(gè)數(shù)據(jù)庫(kù),然后把價(jià)格返回給用戶。
// 到如需要的J2ME類(lèi)
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.rms.*;
// 擴(kuò)展MIDlet類(lèi)來(lái)構(gòu)建我們的自定義MIDlet
public class FundTracker extends MIDlet implements
CommandListener {
file://顯示管理者變量
private Display display = null;
file://MIDlet的表單變量
private RequestForm reqForm = null;
file://MIDlet構(gòu)建器
public FundTracker () {
display = Display.getDisplay(this);
reqForm = new RequestForm("Fund Tracker");
reqForm.initForm();
reqForm.setCommandListener(this);
}
file://開(kāi)始 MIDlet 應(yīng)用程序
protected void startApp() {
display.setCurrent(reqForm);
}
file://暫停 Midlet
protected void pauseApp() {
}
file://銷(xiāo)毀Midlet
protected void destroyApp(boolean unconditional) {
}
file://通過(guò)監(jiān)聽(tīng)者響應(yīng)命令
public void commandAction(Command c, Displayable s) {
if (c == reqForm.getExitCommand()) {
destroyApp(false);
notifyDestroyed();
return;
}
if ((c == reqForm.getGetCommand()) &&
(reqForm.getSymField().getString().length() > 0)) {
getAndDisplayQuote();
} else
{
reqForm.getMsgString().setText("Symbol required");
}
}
file://儲(chǔ)存由#分開(kāi)的成對(duì)的基金字符串和報(bào)價(jià)字符串
private void storeQuote (String fund, String newQuote) {
file://數(shù)據(jù)庫(kù)變量
RecordStore quoteDB = null;
try {
quoteDB = RecordStore.openRecordStore(
"FundQuotes", true);
byte[] data = (fund + "#" + newQuote).getBytes();
int size = data.length;
quoteDB.addRecord(data, 0, size);
quoteDB.closeRecordStore();
}
catch (Exception recordException) {
System.out.println("Unable to store quote and/or
use Fund Quote database.");
}
}
file://通過(guò)QuoteService類(lèi)取回提交的代號(hào)表示的基金報(bào)價(jià)
private void getAndDisplayQuote(){
String fundSymbol = reqForm.getSymField().getString();
if (fundSymbol.length() > 0) {
String theQuote = QuoteService.getQuote(fundSymbol);
if (theQuote != null) {
storeQuote(fundSymbol, theQuote);
reqForm.getMsgString().setText(theQuote);
}
else
reqForm.getMsgString().setText("No quote" +
'\n' + "Check Symbol");
}
}
}
MIDP應(yīng)用程序稱為 MIDlet, 為了創(chuàng)建一個(gè) MIDlet,你必須寫(xiě)一個(gè)擴(kuò)展基本 MIDlet類(lèi)的類(lèi) (就像我們?cè)谏厦娲a段中列出的那樣)。 這有點(diǎn)類(lèi)似常見(jiàn)的 applet或 servlet。 MIDlets獨(dú)有的東西是把多個(gè) MIDlet組成一個(gè) MIDlet套件的能力。 這就允許 MIDlet在一個(gè)單獨(dú)的 JVM環(huán)境中共享資源,比如一個(gè)數(shù)據(jù)庫(kù)等等。 事實(shí)上,我們上面給出的例子還包括一個(gè) MIDlet ( RetrieveQuote,見(jiàn)上段程序),用于取回所報(bào)價(jià)格。 當(dāng)MIDlet被請(qǐng)求時(shí), MIDlet通過(guò)構(gòu)造程序?qū)嵗缓笳{(diào)用實(shí)例的 startApp()方法。
在 FundTracker例子中, MIDlet的用戶界面或顯示是由 Display類(lèi)的一個(gè)實(shí)例管理的。 對(duì)于每個(gè) MIDlet,只有一個(gè)顯示管理器實(shí)例。 所有可以顯示的項(xiàng)目,像屏幕或畫(huà)布(canvas),通過(guò)這個(gè)管理器都能夠成為可見(jiàn)的。因?yàn)樾袆?dòng)電話和呼叫器能力的多樣化,又因?yàn)橛糜谶@些設(shè)備的應(yīng)用程序類(lèi)型的差異, MIDP規(guī)范提供了兩種類(lèi)型的用戶界面。一個(gè)可移植性稍差、明確設(shè)備、低水平的應(yīng)用程序接口,允許圖形元素精確的控制和放置。 這個(gè)接口類(lèi)型是用于應(yīng)用程序特性比較典型的設(shè)備特別設(shè)計(jì)的,比如電子游戲。 一個(gè)可移植性稍好的、抽象的、的 GUI應(yīng)用程序接口,提供來(lái)用于商業(yè)應(yīng)用程序。
我們的例程使用的是的應(yīng)用程序接口和典型的用戶界面組件 (文本框,列表等等 ),是這類(lèi)界面通用的。比如說(shuō),實(shí)際的表單和所有的小組件在一個(gè)單獨(dú)的文件中都已定義。 就像在代碼段一中列出的那樣,當(dāng) MIDlet創(chuàng)建時(shí),一個(gè)表單的實(shí)例與 MIDlet關(guān)聯(lián)。 在調(diào)用 MIDlet startApp()方法的時(shí)候,通過(guò) Display對(duì)象顯示表單。 使用一個(gè)用于表單的類(lèi),允許我們?cè)谖覀兒?jiǎn)單的報(bào)價(jià)檢索應(yīng)用程序中重新使用這個(gè)表單 ( RetrieveQuote )。為了清晰性和風(fēng)格,我們通過(guò)一個(gè)單獨(dú)的類(lèi)來(lái)定義報(bào)價(jià)服務(wù)。 為了演示一般連接器結(jié)構(gòu)的能力,我們的報(bào)價(jià)服務(wù)類(lèi)通過(guò)一個(gè) Connector實(shí)例取回報(bào)價(jià)。
MIDP要求平臺(tái)設(shè)備提供一個(gè)機(jī)制用來(lái)儲(chǔ)存簡(jiǎn)單的數(shù)據(jù)記錄,通過(guò)正常的平臺(tái)事件,比如重新啟動(dòng)和電池更新維護(hù)系統(tǒng)的完整性。 MIDP稱一個(gè)持久數(shù)據(jù)庫(kù)為 RecordStore。 在我們的示例中, MIDlet打開(kāi)并添加一條記錄到 " MutualFundQuotes " RecordStore。 正如我們的演示程序,能添加到 RecordStore中的一種類(lèi)型的記錄是字節(jié)數(shù)組。 相同的 RecordStore是一個(gè)資源,它可以通過(guò)套件共享。 根據(jù) MIDP規(guī)范, 當(dāng) MIDlet從平臺(tái)中刪除后,RecordStore也會(huì)被從平臺(tái)中刪除。
PDA簡(jiǎn)表
Palm公司是開(kāi)發(fā)PDA簡(jiǎn)表規(guī)范的領(lǐng)頭人, 這個(gè)簡(jiǎn)表也是完善了 CLDC,在相當(dāng)長(zhǎng)的一段時(shí)間內(nèi),它都將是 kjava類(lèi)程序包的替代品。 Java規(guī)范建議這個(gè) profile至少應(yīng)當(dāng)提供兩個(gè)核心功能片段: 一個(gè)用戶界面顯示工具包,適合于 "有限的尺寸和深度顯示 "和一個(gè)持久數(shù)據(jù)存儲(chǔ)器機(jī)制。 顯示工具包應(yīng)該是抽象窗口工具包的一個(gè)子集, 而持久機(jī)制將為應(yīng)用程序、數(shù)據(jù)、配置/環(huán)境信息提供簡(jiǎn)單的數(shù)據(jù)存儲(chǔ)。
Foundation簡(jiǎn)表
下面三種簡(jiǎn)表不是非常常見(jiàn), 這三種簡(jiǎn)表的職責(zé)都是為了完善 CDC。 Personal和 RMI簡(jiǎn)表實(shí)際上是 Foundation簡(jiǎn)表的擴(kuò)展。 Foundation簡(jiǎn)表的任務(wù)是擔(dān)任一個(gè)基礎(chǔ)簡(jiǎn)表,便于以后開(kāi)發(fā)出來(lái)的提供圖形用戶接口、 網(wǎng)絡(luò)等功能的簡(jiǎn)表附著在它之上。 除了用于基礎(chǔ)簡(jiǎn)表, Foundation簡(jiǎn)表還提供完整網(wǎng)絡(luò)的支持,不管有沒(méi)有使用圖形用戶接口。
Personal簡(jiǎn)表
在當(dāng)前的規(guī)范需求下, Personal簡(jiǎn)表提供下一代 PersonalJava環(huán)境。這個(gè)簡(jiǎn)表允諾,提供互聯(lián)網(wǎng)連接性和 Web保真度以及一個(gè)能夠運(yùn)行 Java applets的 GUI。
RMI簡(jiǎn)表
回想一下 CDC配置為共享的、固定網(wǎng)絡(luò)連接信息設(shè)備提供小的 Java環(huán)境。 RMI簡(jiǎn)表將通過(guò)提供 Java到 Java的RMI來(lái)協(xié)助提供更好的網(wǎng)絡(luò)連接性。 通過(guò)使用 J2SE ( 1.2.x或更高版本的 ) RMI,這個(gè)簡(jiǎn)表將允許這些網(wǎng)絡(luò)設(shè)備與其他系統(tǒng)應(yīng)用程序交互操作 (這個(gè)系統(tǒng)不必也運(yùn)行 J2ME )。
kjava類(lèi)
正如前面提到的那樣, kjava類(lèi)是初提供的一個(gè)供測(cè)試用的類(lèi),在 Palm設(shè)備上運(yùn)行早期的 KVM和配置版本。 它們將被 PDA簡(jiǎn)表代替。 kjava類(lèi)擴(kuò)展了 CLDC并且提供一個(gè)圖形用戶接口、 Palm數(shù)據(jù)庫(kù)訪問(wèn),簡(jiǎn)單集合類(lèi)和一個(gè)三角法計(jì)算器。
在代碼段2中,我使用 com.sun.kjava重寫(xiě)了 MIDP FundTracker程序,讓它在 Palm上工作。 和前面的程序一樣,這個(gè)簡(jiǎn)單的程序允許用戶輸入一個(gè)公基金代號(hào)并從WWW上的金融報(bào)價(jià)服務(wù)商那里取回報(bào)價(jià)。
kjava應(yīng)用程序被稱作 spotlet。 事實(shí)上,一個(gè)應(yīng)用程序可以由很多 spotlet組成,但是在任何時(shí)間只有一個(gè) spotlet可以顯示在 Palm屏幕上。 在我們的例子中,我們創(chuàng)建一個(gè)基本 spotlet-- RequestFormSpotlet.java,為我們的兩個(gè) spotlets子類(lèi)提供用戶界面。代碼段 2擴(kuò)展了基本的 RequestFormSpotlet以便得到并儲(chǔ)存一個(gè)報(bào)價(jià)。 RetrieveSpotlet也擴(kuò)展了基本 RequestFormSpotlet并允許儲(chǔ)存的報(bào)價(jià)被取回(見(jiàn)圖)
代碼段2
import com.sun.kjava.*;
public final class FundSpotlet extends RequestFormSpotlet {
public static void main (String args[]) {
new FundSpotlet().draw();
}
private void draw() {
initForm();
setTitle("Fund Quote Requested");
}
public void penDown(int x, int y){
if (getExitButton().pressed(x,y)){
getGraphic().playSound(Graphics.SOUND_CONFIRMATION);
System.exit(0);
}
if (getSymField().pressed(x,y))
getSymField().setFocus();
if (getGetButton().pressed(x,y)) {
quoteRequested();
}
}
private void storeQuote (String fund, String newQuote) {
int dbType = 0x46554e44;
int dbCreator = 0x43415454;
com.sun.kjava.Database quoteDB;
try {
quoteDB = new com.sun.kjava.Database(dbType,
dbCreator, com.sun.kjava.Database.READWRITE);
if (!quoteDB .isOpen()) {
com.sun.kjava.Database.create(0, "MutualFundQuotes",
dbCreator, dbType, false);
quoteDB = new com.sun.kjava.Database(dbType,
dbCreator, com.sun.kjava.Database.READWRITE);
}
byte[] data = (fund + "#" + newQuote).getBytes();
quoteDB.addRecord(data);
quoteDB.close();
}
catch (Exception recordException) {
System.out.println("Unable to store quote and/or use
Mutual Fund Quote database.");
}
}
private void getAndDisplayQuote() {
String fundSymbol = getSymField().getText();
if (fundSymbol.length() > 0) {
String theQuote = QuoteService.getQuote(fundSymbol);
if (theQuote != null) {
storeQuote(fundSymbol, theQuote);
message(theQuote);
}
else
message("No quote. Check Symbol");
}
}
private void quoteRequested() {
message("");
getGraphic().playSound(Graphics.SOUND_STARTUP);
if ((getSymField().getText().length() > 0)) {
getAndDisplayQuote();
} else
{
message("Symbol required!");
}
}
}
在 RequestFormSpotlet程序中,類(lèi)似于 MIDP中的 Display對(duì)象,單獨(dú)的 Graphics管理許多 spotlet用戶界面顯示。它考慮到了屏幕會(huì)被清除,顯示邊界會(huì)被建立。 不象 MIDlet,沒(méi)有屏幕或畫(huà)布對(duì)象來(lái)讓我們添加用戶界面小組件, 取而代之的是按鈕、文本字段等等,直接描畫(huà)在 spotlet上。 paint()方法利用圖形環(huán)境從的 Graphics在屏幕上顯示小組件。
我們的MIDP程序的 QuoteService類(lèi)的大部分可以重新使用。 因?yàn)?kjava沒(méi)有象 MIDP中HttpConnection這樣特定的連接器界面,所以我們必須利用更多標(biāo)準(zhǔn)的一般的連接器結(jié)構(gòu)表單獲取 HTTP鏈接。 為了做到這一點(diǎn),使用代碼段 3中的代碼替換 getQuotePage()方法。注意注意使用 Connector,就像在 MIDP中我們使用 HttpConnection一樣。
代碼段3
private static String getQuotePage(String symbolString) {
StringBuffer quotePage = new StringBuffer();
int ch;
try {
InputStream in = Connector.openInputStream (
"testhttp://someurl/some_application?page=++&mode=fund&symbol="+
symbolString);
while ((ch = in.read()) > 0) {
quotePage.append((char)ch);
}
in.close();
return quotePage.toString();
} catch (IOException ex) {
System.out.println("Exception reading quote from
HTTP Connection");
return null;
}
}
Palm設(shè)備廣泛利用數(shù)據(jù)庫(kù), 你的 Palm中的通訊簿、備忘錄和記事本應(yīng)用程序都與數(shù)據(jù)庫(kù)有關(guān)。 kjava程序包提供了一個(gè)非常小的 Database類(lèi),不僅可以創(chuàng)建并保持應(yīng)用程序數(shù)據(jù),而且可以訪問(wèn)現(xiàn)有的數(shù)據(jù)庫(kù)。 如果你熟悉 Palm數(shù)據(jù)庫(kù),你可能會(huì)對(duì) kjava Database類(lèi)提供的功能和信息感到失望。 然而,請(qǐng)?jiān)俅斡涀。?kjava只是一個(gè)演示的版本。
在我們的例子中,我們的 spotlet訪問(wèn)一個(gè) Palm數(shù)據(jù)庫(kù) (如果不存在的話,則創(chuàng)建一個(gè)新的數(shù)據(jù)庫(kù))來(lái)儲(chǔ)存公基金報(bào)價(jià)。每個(gè) Palm數(shù)據(jù)庫(kù)都必須有名字、創(chuàng)建者 ID (一個(gè) Palm登記的的標(biāo)識(shí)號(hào) ) 和一個(gè)指定到某個(gè)單獨(dú)應(yīng)用程序的類(lèi)型號(hào)。 試圖打開(kāi)數(shù)據(jù)庫(kù)要通過(guò)嘗試創(chuàng)建一個(gè)帶有 ID信息的數(shù)據(jù)庫(kù)實(shí)例來(lái)實(shí)現(xiàn)。 就象 MIDP RecordStore,記錄被添加進(jìn) kjava數(shù)據(jù)庫(kù),通過(guò)把一個(gè)字節(jié)數(shù)組當(dāng)成記錄添加到數(shù)據(jù)庫(kù)中的形式。
五、J2ME規(guī)范
在 J2ME內(nèi)還有很多子規(guī)范, J2ME的重要的部分如下:PersonalJava、K虛擬機(jī) (KVM)、Java嵌入服務(wù)器以及 PersonalJava的兩個(gè)擴(kuò)展規(guī)范: JavaPhone和 JavaTV應(yīng)用程序接口。 你可以想象, JavaPhone是一個(gè)定位于無(wú)線電智能電話和互聯(lián)網(wǎng)絡(luò)可視電話的應(yīng)用程序接口,而 JavaTV則滿足機(jī)頂盒市場(chǎng)的需求。
下面我想詳細(xì)的談一談以上的規(guī)范:
1、PersonalJava
PersonalJava應(yīng)用程序環(huán)境目標(biāo)是 Web連接消費(fèi)設(shè)備----常常執(zhí)行來(lái)自網(wǎng)絡(luò)的小應(yīng)用程序。問(wèn)題是 PersonalJava如何適合 J2ME的配置和簡(jiǎn)表方案。 答案是 PersonalJava將被包容進(jìn) Connected Device Configuration中,終將被定義為 Personal簡(jiǎn)表,即前面所談到的Personal簡(jiǎn)表。
另一方面,有一段時(shí)間將有兩個(gè) Java應(yīng)用程序接口為嵌入開(kāi)發(fā)世界服務(wù): PersonalJava和 EmbeddedJava。 PersonalJava偎依在 J2ME大傘之下, 可為什么 EmbeddedJava不呢? EmbeddedJava不和 PersonalJava同在 J2ME內(nèi),是因?yàn)樵?PersonalJava和 EmbeddedJava應(yīng)用程序之間有一個(gè)基本的差別。 PersonalJava應(yīng)用程序期望連接到某類(lèi)網(wǎng)絡(luò)中下載并執(zhí)行小應(yīng)用程序。 按照這種觀點(diǎn), PersonalJava設(shè)備就是一般用途的消費(fèi)設(shè)備; 它們的能力可以被擴(kuò)展。
相比之下, EmbeddedJava設(shè)備則慘了點(diǎn)。 它們執(zhí)行的功能都非常具體的,基本沒(méi)有必要提供下載新的代碼到 EmbeddedJava設(shè)備的能力。 Hence, PersonalJava設(shè)備使用可擴(kuò)展 Java應(yīng)用程序接口; 而EmbeddedJava設(shè)備則沒(méi)有,因?yàn)闆](méi)有必要使用。
PersonalJava可以以兩種形式得到: 由原碼形式的,提供給那些對(duì)把PersonalJava移植到其他設(shè)備感興趣的開(kāi)發(fā)者,那些已經(jīng)把 PersonalJava移植到某個(gè)具體的操作系統(tǒng)和處理機(jī)的組織提供二進(jìn)制形式的 PersonalJava環(huán)境。有興趣探索 PersonalJava的開(kāi)發(fā)者如果沒(méi)有二進(jìn)制平臺(tái)也可以使用 PersonalJava模擬環(huán)境 ( PJEE )。 這個(gè)模擬器運(yùn)行于 Solaris/SPARC或 Windows,并且在許多配置中可用。 這些多種多樣的配置基于“ look and feel”和類(lèi)庫(kù)支持 (環(huán)境是否提供 PersonalJava規(guī)范中規(guī)定的限度的或的類(lèi)庫(kù))。PJEE包括類(lèi)文件,一個(gè)應(yīng)用程序 launcher和一個(gè) appletviewer (兩者都是為了調(diào)試功能并使其化)和其它的附帶的文件 (例如字體敘述文件)。
J2ME家族的另一位成員 JavaCheck實(shí)用程序,提供了 PersonalJava的補(bǔ)充支持。 你把應(yīng)用程序傳過(guò) JavaCheck,它將告訴你你的應(yīng)用程序在一個(gè) PersonalJava環(huán)境中能否順利地執(zhí)行。 JavaCheck檢查類(lèi)之間的依賴關(guān)系,如果應(yīng)用程序調(diào)用了一個(gè)在 PersonalJava不可用的應(yīng)用程序接口,它就會(huì)給出一個(gè)警報(bào)信號(hào)。 (據(jù)我所知,目前有兩種JavaCheck的版本可用,一個(gè)是用于檢驗(yàn) PersonalJava 1.0版應(yīng)用程序,另一個(gè)用于檢驗(yàn) 1.1.x版程序。 當(dāng)前的 PersonalJava應(yīng)用程序接口規(guī)范是 1.2,用于這一版本的 JavaCheck還沒(méi)有。 讀者請(qǐng)去Sun相關(guān)網(wǎng)站去看看( http : file://java.sun.com/products/personaljava)。
2、KVM
前面我也說(shuō)過(guò),KVM是用于 J2ME平臺(tái)小的虛擬機(jī),并且是用于CLDC配置的虛擬機(jī)。可是J2ME應(yīng)用程序并不一定非要使用 KVM,J2ME技術(shù)可以使用任何虛擬機(jī),不過(guò)至少應(yīng)當(dāng)有 KVM這樣的功能。
為了滿足基于KVM的設(shè)備一般只有狹小的內(nèi)存空間和有限的處理能力的事實(shí), KVM使用 C編寫(xiě) (它不是現(xiàn)有的VM改進(jìn)了的以后的產(chǎn)品)。 此外, KVM是模塊化的, 也就是說(shuō),它是由模塊構(gòu)建的,當(dāng)某個(gè)模塊實(shí)現(xiàn)了預(yù)先設(shè)定的目標(biāo)后,就可以很容易地把這一模塊卸載。 可選的某塊包括: 大的數(shù)據(jù)類(lèi)型 ( long、 float和 double ),多維數(shù)組、類(lèi)文件驗(yàn)證等。
KVM的本地界面以輕便性為原則構(gòu)建,所以在KVM中任務(wù)切換不依賴硬件產(chǎn)生的記時(shí)器中斷,因此在這種意思上來(lái)說(shuō)不是搶先式。任務(wù)切換發(fā)生在虛擬機(jī)執(zhí)行了一個(gè)預(yù)設(shè)編號(hào)的字節(jié)碼之后。 并且, KVM的無(wú)用單元收集利用一個(gè)標(biāo)記清掃(mark and sweep)算法來(lái)實(shí)現(xiàn)無(wú)用單元釋放。 因此,對(duì)象引用是直接的,就像標(biāo)準(zhǔn) Java一樣。
當(dāng)然,除了虛擬機(jī)以外還有許多可用的執(zhí)行環(huán)境,在小型設(shè)備中,虛擬機(jī)必須要么被擴(kuò)展,要么在附加工具協(xié)助下提供一個(gè)更加完整的運(yùn)行期環(huán)境,正是這個(gè)原因, KVM需要附帶的工具,比如說(shuō), JavaCodeCompact工具提供了預(yù)鏈接和預(yù)加載類(lèi), 允許Java類(lèi)被直接地鏈接進(jìn)虛擬機(jī)中。((設(shè)備上所有的應(yīng)用程序使用的類(lèi) can直接地嵌入虛擬機(jī)。)
KVM一個(gè)可選的附件就是 Java Application Manager ( Java應(yīng)用程序管理器,簡(jiǎn)稱 JAM )。JAM的工作就是處理下載、安裝、執(zhí)行和卸載 CLDC設(shè)備上的應(yīng)用程序的細(xì)節(jié)問(wèn)題,因?yàn)橘Y源有限,在CLDC設(shè)備上有可能不存在這些功能。JAM也處理更新安裝應(yīng)用程序的操作。(如果更新過(guò)程失敗,它甚至可以重新使用舊的應(yīng)用程序。 )
3、Java Embedded Server(Java嵌入服務(wù)器)
Java Embedded Server( Java嵌入服務(wù)器,簡(jiǎn)稱 JES),在 PersonalJava基礎(chǔ)上建立,是一個(gè)用于嵌入式網(wǎng)絡(luò)設(shè)備的運(yùn)行期環(huán)境。為了理解 JES,你必須理解兩個(gè)核心概念:服務(wù)和服務(wù)空間結(jié)構(gòu)。后者是前者的容器。服務(wù)程序是運(yùn)行于一個(gè) JES服務(wù)器上的組件化程序;服務(wù)空間結(jié)構(gòu)是為服務(wù)程序提供生命周期 支持的環(huán)境。
技術(shù)上說(shuō),服務(wù)程序是界面的實(shí)現(xiàn),事實(shí)上,它是一個(gè)實(shí)現(xiàn)特定活動(dòng)的Java類(lèi)集合。比如說(shuō),假如把 JES配置為一個(gè)家庭的氣候控制系統(tǒng)的服務(wù)器,可以把從模數(shù)轉(zhuǎn)換器讀到的溫度數(shù)據(jù)放進(jìn)一個(gè)數(shù)據(jù)組件程序中。我就可以稱這個(gè)組件為ReadThermostats服務(wù)程序。
在 JES的領(lǐng)域,服務(wù)的封裝媒介稱為 bundle。簡(jiǎn)單地說(shuō),bundle就是一個(gè)帶有特殊內(nèi)容的JAR文件。服務(wù)程序和bundle之間有一對(duì)一關(guān)系,一個(gè)bundle帶有一個(gè)服務(wù)程序。服務(wù)程序和 bundle之間有一對(duì)一關(guān)系,一個(gè) bundle帶有一個(gè)服務(wù)程序。可這也不一定,一個(gè) bundle可以設(shè)置多個(gè)服務(wù)程序索引 (注意, JES提供的所有的核心服務(wù),每個(gè) bundle中只有一個(gè) )。
正如前面提到的那樣,服務(wù)空間的一項(xiàng)工作就是管理服務(wù)程序的生命周期,這個(gè)工作的很大的部分包括解決服務(wù)隸屬關(guān)系。bundle內(nèi)容的一個(gè)重要的部分是bundle服務(wù)的依賴信息。所以,當(dāng)服務(wù)空間打開(kāi)一個(gè)bundle安裝它的服務(wù)時(shí),服務(wù)空間就可以確定外部需要什么服務(wù)。而且,一個(gè)服務(wù)的依賴關(guān)系并不是靜止不變的,它們可以隨某些事件改變。比如說(shuō)當(dāng)服務(wù)程序更新時(shí)的變化就是一個(gè)很好的例子。一個(gè)服務(wù)的新的版本可以添加或去除依賴關(guān)系。服務(wù)空間跟蹤并解決這樣的動(dòng)態(tài)依賴關(guān)系。如果服務(wù)空間處理所有服務(wù)程序的生命周期,這就暗示了服務(wù)空間被賦予知曉一切的能力,那就是說(shuō),它能夠推論結(jié)構(gòu)、依賴、安裝的細(xì)微差別等所有它負(fù)責(zé)的服務(wù)。服務(wù)空間通過(guò)在 bundle內(nèi)伴隨服務(wù)的 Java代碼模塊處理一些任務(wù),這些模塊被稱作 wizard(向?qū)ВES向?qū)歉鶕?jù)它們完成的任務(wù)命名的:
Dependencies -向?qū)Ц嬖V調(diào)用者一個(gè)bundle依賴關(guān)系是什么。
Installer-向?qū)幚韇undle中服務(wù)的安裝和刪除操作。
Activator -向?qū)е廊绾螁?dòng)和終止服務(wù)。
Updater -向?qū)Э丶耣undle中的服務(wù)。(更新向?qū)Р粌H知道更新一個(gè)服務(wù),而且知道在何時(shí)和什么情況下更新服務(wù)。 )
About -這個(gè)向?qū)В拖袼Q意味的那樣,返回關(guān)于 bundle內(nèi)容的信息。
Dispatcher -這是一種元向?qū)В╩eta-wizard)。服務(wù)空間調(diào)用dispatcher向?qū)Фㄎ灰粋€(gè)bundle的其他向?qū)А?
當(dāng)一個(gè) JES服務(wù)器啟動(dòng)的時(shí)候,服務(wù)空間并不是完全沒(méi)有啟動(dòng)服務(wù)。JES定義一組核心服務(wù)(可選),這些都是任何 JES服務(wù)器的組成部分。這些核心服務(wù)包含:
HTTP服務(wù)
日志 -記錄錯(cuò)誤和事件日志
日期 -精確到秒的日期/時(shí)間服務(wù)
連接管理器 -提供網(wǎng)絡(luò)服務(wù)和Socket綁定,也處理連接接收。
線程管理器 -管理服務(wù)器提供的線程。thread管理器支持線程池并允許有效使用線程上界的規(guī)范。
計(jì)劃程序 -提供未來(lái)的事件計(jì)劃安排 (可用于告訴服務(wù)器某某動(dòng)作必須在某某事件發(fā)生 )
RMI
SNMP
控制臺(tái) -提供遠(yuǎn)程管理服務(wù)器功能
基于 HTTP的遠(yuǎn)程應(yīng)用程序接口實(shí)現(xiàn)
基于 RMI的遠(yuǎn)程應(yīng)用程序接口實(shí)現(xiàn)
如果你把服務(wù)空間結(jié)構(gòu)當(dāng)成 JavaBean中的容器的話, JES就變得容易理解了。在這種類(lèi)比關(guān)系中,服務(wù)程序就相當(dāng) JavaBean。那么,正象組件容器提供一個(gè)環(huán)境供 JavaBeans實(shí)例化、運(yùn)行一樣,服務(wù)空間就是以實(shí)例化的服務(wù)的聚集地。服務(wù)空間管理安裝、實(shí)例化、執(zhí)行、終止以及卸載服務(wù);它也提供應(yīng)用程序接口供服務(wù)交互作用。
到目前為止,大部分人都已非常熟悉 Java 2平臺(tái),以及 Sun如何把 Java技術(shù)分成三個(gè)版本 (標(biāo)準(zhǔn)版、袖珍版以及企業(yè)版),Sun 在1999年6月時(shí)推出了 Java 2袖珍版 (J2ME)來(lái)滿足消費(fèi)電子和嵌入設(shè)備的需要。J2ME是為了那些使用有限的能源、有限的網(wǎng)絡(luò)連接 (常常是無(wú)線連接)以及有限圖形用戶界面能力的設(shè)備開(kāi)發(fā)的。它初的目標(biāo)是 16位或 32位處理器,16 MHz時(shí)鐘頻率, 512K或更少內(nèi)存的設(shè)備。乍一看之下, J2ME就像一個(gè)沒(méi)有綁定明顯主題的松散的應(yīng)用程序接口和技術(shù)規(guī)范。我們想通過(guò)說(shuō)它不是什么東西的方法來(lái)描述它,它不是一組用于臺(tái)式機(jī) Java應(yīng)用程序規(guī)范,如果你再觀察仔細(xì)一些,你會(huì)發(fā)現(xiàn)所有的 J2ME組件都圍繞一個(gè)中心,這些中心被稱為configuration(配置 ,Sun的市場(chǎng)營(yíng)銷(xiāo)資料也稱它們 design centers,設(shè)計(jì)中心),它們中間的每一個(gè)都是用于消費(fèi)電子和嵌入設(shè)備的特別的類(lèi)。
Connected limited device configuration(有限連接設(shè)備配置,簡(jiǎn)稱 CLDC ) 這個(gè)配置定義了 Java應(yīng)用程序接口以及支持手持設(shè)備的技術(shù),就像 Sun的文檔中所描述的那樣, " devices that you hold in your hand(你握在手中的設(shè)備) " Palm序列手持設(shè)備可能是這一領(lǐng)域的設(shè)備的的例子,特別是它有開(kāi)發(fā) CLDC的功能以及 Palm設(shè)備運(yùn)行期系統(tǒng)可用。
Connected device configuration(連接設(shè)備配置 CDC ) 這個(gè)配置定義支持象 Sun文檔中所說(shuō), " devices that you plug into plug into the wall(你插入墻的設(shè)備)的設(shè)備的應(yīng)用程序接口和技術(shù),這樣的設(shè)備的一個(gè)例子可能就是機(jī)頂盒。
這兩種配置不同的地方就在于它們應(yīng)用于的裝置的能力, CLDC設(shè)備的處理器能力有限 (與臺(tái)式機(jī)系統(tǒng)比較 ),并且存儲(chǔ)器大小一般也只在128 KB到 512 KB之間, 與此同時(shí),CDC系統(tǒng)就不同了,它可能有 32位或 64位處理器,以及有限的存儲(chǔ)容量,不過(guò)它的下限也得超過(guò)512K。 它遵循的原則就是,每個(gè)不同的能力硬件的配置都將被不同的虛擬機(jī)支持。 基于 CDC的系統(tǒng)使用一個(gè)功能強(qiáng)勁的虛擬機(jī),而基于 CLDC系統(tǒng)的使用 KVM 。
每個(gè)配置代表一種低水平的,基本的應(yīng)用程序接口,在這兩個(gè)相似基礎(chǔ)之上是 profile(簡(jiǎn)表),用于特殊設(shè)備的額外的應(yīng)用程序接口。 我想通過(guò)看一張來(lái)自SUN提供的文檔中的圖表 (參見(jiàn)圖 1 )來(lái)解釋這其中的關(guān)系。
J2ME的體系結(jié)構(gòu)被橫向地分成三層,縱向分成兩部分。配置包括一個(gè)控制配置核心類(lèi)的虛擬機(jī), 具體的簡(jiǎn)表位于每個(gè)配置之上。
J2ME現(xiàn)在定義兩個(gè)配置, Connected Device configuration(連接設(shè)備配置 CDC )和限制性更強(qiáng)的 Connected Limited Device Configuration (有限連接設(shè)備配置)。 簡(jiǎn)表的實(shí)現(xiàn)是 Java應(yīng)用程序接口的一個(gè)集合,用于適應(yīng)被定義配置的應(yīng)用程序接口提供的服務(wù),簡(jiǎn)表是一個(gè)完整的運(yùn)行環(huán)境,一個(gè)在簡(jiǎn)表上執(zhí)行的應(yīng)用程序不需要額外的支持類(lèi)。
J2ME沒(méi)有定義滿足這兩種配置的標(biāo)準(zhǔn)化用戶接口,Sun也承認(rèn)現(xiàn)在的消費(fèi)設(shè)備多種多樣,用戶界面也各不一樣,所以定義一個(gè)可用于所有用戶的界面是一場(chǎng)失敗的戰(zhàn)爭(zhēng)。 J2ME中的用戶界面定義在簡(jiǎn)表中。
二、J2ME的體系結(jié)構(gòu)
現(xiàn)在個(gè)人計(jì)算機(jī)系統(tǒng)的數(shù)量和種類(lèi)已經(jīng)發(fā)展到無(wú)法控制的地步,請(qǐng)你想一想,你編寫(xiě)的程序運(yùn)行在“信息家電”舞臺(tái)的情景吧,這些信息家電包括呼叫器,行動(dòng)電話,像Palm這樣的個(gè)人數(shù)字助手(PDA),電視機(jī)頂盒,POS終端以及其他的消費(fèi)電子設(shè)備。現(xiàn)在全世界上光是手提電話生產(chǎn)商就有許多,更不用說(shuō)別的家電設(shè)備了,而且每一種家電設(shè)備又有不同的特性和界面。所以,你可以想到, Java應(yīng)用程序的輕便性以及能夠解決開(kāi)發(fā)這么許多不同的設(shè)備程序的能力,使大家對(duì)J2ME有很大的期許。當(dāng)然,為了更好的開(kāi)發(fā)這些信息家電,就要求把Java的精髓壓縮進(jìn)一個(gè)非常小的程序包中,這就是J2ME。
J2ME是一種通過(guò)許多部件和規(guī)范的技術(shù), 這眾多的部件和規(guī)范幫助 J2ME來(lái)滿足這眾多的消費(fèi)產(chǎn)品的不同的需要。和所有的爪哇程式語(yǔ)言技術(shù)一樣,在它的核心屬于一種虛擬機(jī)。 就像使用所有 Java技術(shù)一樣,J2ME的核心也在一種虛擬機(jī)中。 初,用于 J2ME應(yīng)用程序虛擬機(jī)的被稱作 Kilobyte virtual machine或簡(jiǎn)稱 KVM。就像它名稱的含義, KVM比較小,通常只有 128K或更少。這比起我們通常了解和使用的 Java 2標(biāo)準(zhǔn)版 Java虛擬機(jī) ( JVM )的 32 MB來(lái)說(shuō)就小得多了。
用于連接虛擬機(jī)的是一系列配置和簡(jiǎn)表,它們提供了用于特定 J2ME環(huán)境的類(lèi)應(yīng)用程序接口(見(jiàn)圖二)。 每個(gè)配置和簡(jiǎn)表處理一般或具體的消費(fèi)產(chǎn)品,配置和簡(jiǎn)表規(guī)范是由多種多樣的設(shè)備生產(chǎn)商和用戶共同開(kāi)發(fā)并建立的。配置是用于一組通用設(shè)備的小的 Java平臺(tái), 常常歸為一種橫向的設(shè)備分組,相對(duì)來(lái)說(shuō),橫向分組設(shè)備是那些共享相同的內(nèi)存安排,通信帶寬,能量需求以及用戶能力的設(shè)備,一般認(rèn)為配置能夠提供這眾多的設(shè)備的所有需求。
Java虛擬機(jī)是 J2ME技術(shù)的核心,但是配置和簡(jiǎn)表提供特殊環(huán)境的類(lèi)應(yīng)用程序接口。配置是用于一組通用設(shè)備的小的 Java平臺(tái),而簡(jiǎn)表則為具體的設(shè)備家族或特別的應(yīng)用程序提供更具體的能力。
J2ME領(lǐng)域的新的開(kāi)發(fā)者常常被這些事實(shí)困惑的, 事實(shí)上, Sun的個(gè)配置(現(xiàn)在只是一種配置的引用實(shí)現(xiàn) )帶有稱為 KVM的虛擬機(jī)引用實(shí)現(xiàn), KVM滿足配置的虛擬機(jī)的必要條件。然而, Sun的 KVM也可以被另外一個(gè)虛擬機(jī)所代替,現(xiàn)在, 正是因?yàn)榕渲煤吞摂M機(jī)結(jié)合得有點(diǎn)緊密,因此導(dǎo)致了這么多的混亂。
另一方面,簡(jiǎn)表完善了 配置,為某個(gè)具體的設(shè)備家族或某個(gè)具體的工業(yè)片段應(yīng)用程序提供更高的性能。 換言之, 簡(jiǎn)表為具體的縱向市場(chǎng)的設(shè)備比如說(shuō)行動(dòng)電話提供更多的性能。這里的關(guān)鍵就是 簡(jiǎn)表必須完善 配置, 沒(méi)有 配置和虛擬機(jī)提供核心類(lèi)應(yīng)用程序接口和運(yùn)行期環(huán)境的話,簡(jiǎn)表也不會(huì)工作。
通常,簡(jiǎn)表為一種給定的垂直分組設(shè)備提供用戶界面、輸入法、持久性機(jī)制。這類(lèi) 簡(jiǎn)表被認(rèn)為是發(fā)展這些設(shè)備應(yīng)用程序的完整的工具包。我們見(jiàn)到多的應(yīng)用程序簡(jiǎn)表的例子就移動(dòng)電話簡(jiǎn)表和個(gè)人數(shù)字助手(PDA)簡(jiǎn)表,其他簡(jiǎn)表為范圍寬廣的設(shè)備提供非常特殊的功能或應(yīng)用程序可移植性,這方面的例子就是提供遠(yuǎn)程方法調(diào)用 ( RMI )功能的簡(jiǎn)表和提供統(tǒng)一銀行事務(wù)的簡(jiǎn)表。
虛擬機(jī)、 配置、 簡(jiǎn)表…你是不是已經(jīng)被搞迷糊了? 如果這樣的話,我們就來(lái)簡(jiǎn)化一下 J2ME體系結(jié)構(gòu)吧。 如果你想為小型信息家電編寫(xiě) Java應(yīng)用程序的話,你就需要兩個(gè)前提:一個(gè) 配置和至少一個(gè) 簡(jiǎn)表。 現(xiàn)在, 一般是配置捆綁了虛擬機(jī)和一套針對(duì)你的平臺(tái)所能夠用的橫向分組設(shè)備的Java類(lèi)庫(kù)。其次,你至少還需要一個(gè) 簡(jiǎn)表來(lái)為你的平臺(tái)提供附加的 Java類(lèi),這個(gè) 簡(jiǎn)表通常會(huì)為你的設(shè)備提供用戶界面、輸入和數(shù)據(jù)庫(kù)類(lèi)。有了這兩個(gè)前提,你就了使用 Java為你的設(shè)備編寫(xiě)應(yīng)用程序的基本的J2ME環(huán)境。
三、詳細(xì)談?wù)凧2ME配置
J2ME可以在好幾個(gè)不同的配置中進(jìn)行配置。就像先前提到的,每個(gè)配置為一組通用設(shè)備提供小的 Java平臺(tái),到目前為止,只有兩種配置規(guī)范。通過(guò) Java規(guī)范定義的這兩種配置是 Connected Limited Device Configuration (有限連接設(shè)備配置, CLDC )和 Connected Device Configuration (連接設(shè)備配置 CDC )。
CLDC是為使用較小的存儲(chǔ)容量的設(shè)備設(shè)計(jì)的 (參見(jiàn)圖3 )。 CLDC用于內(nèi)存在128到 512K之間的消費(fèi)電子設(shè)備, 這一類(lèi)別中典型代表的設(shè)備包含呼叫器、行動(dòng)電話、PDA和POS終端;而另一方面, CDC用于比 PC機(jī)小但是具有比 512K內(nèi)存多的設(shè)備,這一類(lèi)設(shè)備包括互聯(lián)網(wǎng)絡(luò)電視系統(tǒng)、機(jī)頂盒、POS系統(tǒng)、汽車(chē)導(dǎo)航以及娛樂(lè)系統(tǒng)。一般來(lái)說(shuō), CDC使小型設(shè)備只要具有少量的資源,至少比臺(tái)式機(jī)要少的資源就能進(jìn)行Java編程,而CLDC使小型設(shè)備所擁有的資源只要比一張智能卡多一點(diǎn)就可以進(jìn)行Java編程了。
J2ME有兩個(gè)配置CLDC和 CDC,CLDC是為使用較小的存儲(chǔ)容量的設(shè)備設(shè)計(jì)的,而CDC用于比 PC機(jī)小但是具有比 512K內(nèi)存多的設(shè)備。
除了在容量大小和能力上對(duì)虛擬機(jī)規(guī)定了必要條件,配置還規(guī)定了類(lèi)應(yīng)用程序接口要包含常見(jiàn)的 java.io、 java.net、 java.util和 java.lang包,配置可能還要包括其他需要的程序包。
CLDC
CLDC起源可以追溯到1999年JavaOne大會(huì)上介紹的Sun的個(gè)袖珍版 Java和個(gè) KVM以及相關(guān)的類(lèi)庫(kù),雖然 CLDC和所有的配置都滿足成為虛擬機(jī)的條件,可它本身還不是虛擬機(jī),CLDC的引用實(shí)現(xiàn)只是包含在當(dāng)前的分布中的 KVM。
根據(jù)規(guī)范中所說(shuō),運(yùn)行 CLDC的設(shè)備應(yīng)該有 512K或更少的內(nèi)存空間、一個(gè)有限的電源供給 (通常是使用電池)、有限的或斷斷續(xù)續(xù)的網(wǎng)絡(luò)連接性 ( 9600 bps或更少 )以及多樣化的用戶界面甚至沒(méi)有用戶界面。 通常說(shuō)來(lái),這個(gè)配置是為個(gè)人化的、移動(dòng)的、有限連接信息設(shè)備而設(shè)計(jì),比如呼叫器、移動(dòng)電話和 PDA等。
與 J2SE相比, CLDC缺少下列所說(shuō)的這些特征:
AWT(抽象窗口開(kāi)發(fā)包), Swing或其他圖形庫(kù)
用戶定義類(lèi)裝載器
類(lèi)實(shí)例的終化
弱的引用
RMI
Reflection(映射)
CLDC有四個(gè)包: java.lang、 java.util、 java.io和 javax.microedition。 除了 microedition包以外,其他的這幾個(gè)包都是J2SE包的核心子集,CLDC采用這些J2SE類(lèi)庫(kù),但是把其中一些在微型設(shè)備中用不到類(lèi)、屬性、方法去掉了。因此 CLDC類(lèi)庫(kù)有許多細(xì)微的差別。 如果您想研究J2SE和 CLDC類(lèi)庫(kù)之間的差別,請(qǐng)參閱相關(guān)文檔,在此就不詳細(xì)說(shuō)明了。
想要理解為什么CLDC去除這么多J2SE中重要的類(lèi)和特征,請(qǐng)回想一下與 CLDC相關(guān)的兩條基本原理。首先,它只有 512K的內(nèi)存空間, 而像RMI和映射需要的內(nèi)存太大了。 其次,配置必須滿足為一組通用設(shè)備提供小的 Java平臺(tái)。 在個(gè)人移動(dòng)信息設(shè)備領(lǐng)域中,許多系統(tǒng)都不能支持 J2SE中的眾多的特征。 例如,許多消費(fèi)電子產(chǎn)品不能支持浮點(diǎn)數(shù); 因此 Float(浮點(diǎn)類(lèi))和 Double(雙精度類(lèi))就被刪除了。 再看另外一個(gè)例子,許多系統(tǒng)沒(méi)有或不提供訪問(wèn)一個(gè)文件系統(tǒng)的功能或權(quán)限。 因此與文件有關(guān)的類(lèi)也被丟棄了。又如,錯(cuò)誤處理是一個(gè)代價(jià)非常高的過(guò)程處理,在許多消費(fèi)電子設(shè)備中,故障恢復(fù)是很難的甚至是不可能的。 所以在 CLDC中,許多錯(cuò)誤處理類(lèi)也被刪除了。
java.microedition程序包提供了一個(gè)一般的結(jié)構(gòu)來(lái)替代許多 J2SE網(wǎng)絡(luò)輸入/輸出類(lèi)。 CLDC一般連接器結(jié)構(gòu)還定義了一個(gè) Connector類(lèi),允許許多不同類(lèi)型的連接能夠使用靜態(tài)方法,下表列出使用同一個(gè)Connector類(lèi)創(chuàng)建和打開(kāi)五種不同類(lèi)型的連接的方法:
HTTP Connector.open("http://www.xyz.com");
套接字 Connector.open("socket://111.222.111.222:9000");
通訊端口 Connector.open("comm:1;baudrate=9600");
數(shù)據(jù)報(bào) Connector.open("datagram://111.222.111.222");
文件 Connector.open("file:/xyz.dat");
一般連接器結(jié)構(gòu)提供給應(yīng)用程序開(kāi)發(fā)者一個(gè)到通用低水平硬件的簡(jiǎn)單的映射表。成功執(zhí)行 open語(yǔ)句將返回一個(gè)實(shí)現(xiàn)一般連接界面的對(duì)象。
CDC
CDC涵蓋了個(gè)人電腦與有至少 512K內(nèi)存的小型設(shè)備之間的中間地帶。現(xiàn)在,這一類(lèi)設(shè)備通常是共享的、固定的 (不用移動(dòng))網(wǎng)絡(luò)連接信息設(shè)備,像電視機(jī)機(jī)頂盒,網(wǎng)絡(luò)電視系統(tǒng)、互聯(lián)網(wǎng)電話與汽車(chē)導(dǎo)航/娛樂(lè)系統(tǒng)等等。
首先,CDC基于 J2SE 1.3應(yīng)用程序接口,包含所有定義在CLDC規(guī)范(包括 javax.microedition程序包)中的Java語(yǔ)言應(yīng)用程序接口。與CLDC相比, CLDC所有缺少的特性和類(lèi)在 CDC中都被補(bǔ)齊,包含映射、終化、所有的錯(cuò)誤處理類(lèi)、浮點(diǎn)數(shù)、屬性、輸入/輸出 ( File、 FileInputStream等等 )和弱的引用。 一般說(shuō)來(lái), CDC中預(yù)期的類(lèi)包括一個(gè)J2SE子集和一個(gè)完整的 CLDC超集,如圖4中所示:
就像使用所有的配置一樣,CDC有基層虛擬機(jī)的具體的必要條件。 根據(jù) CDC規(guī)范,基層虛擬機(jī)必須提供實(shí)現(xiàn)完整的 Java虛擬機(jī)的支持 。 如果虛擬機(jī)實(shí)現(xiàn)有一個(gè)用于激活設(shè)備的本地方法的界面,它必須兼容 JNI 1.1版本。 如果虛擬機(jī)實(shí)現(xiàn)有一個(gè)調(diào)試界面,它必須兼容 Java虛擬機(jī)調(diào)試界面 ( JVMDI )規(guī)范。 如果虛擬機(jī)有一個(gè)簡(jiǎn)表界面,它必須兼容 Java虛擬機(jī)簡(jiǎn)表界面 ( JVMPI )規(guī)范。 可見(jiàn),為了實(shí)現(xiàn)這些功能,CDC肯定會(huì)變得很大,就不能稱其為K虛擬機(jī)了,因此,我們通常稱用于CDC的虛擬機(jī)為 CVM,這里的 C代表 compact、connected、consumer。
四、談?wù)凧2ME簡(jiǎn)表
雖然配置為一組通用設(shè)備提供了小的 Java平臺(tái),但是應(yīng)用程序開(kāi)發(fā)者感興趣的是為一個(gè)個(gè)別的設(shè)備生產(chǎn)應(yīng)用程序,當(dāng)他們只是使用配置的話,他們編寫(xiě)的應(yīng)用程序就會(huì)有一些欠缺。 配置必須滿足所有的設(shè)備的小的要求, 用戶界面、輸入機(jī)制和數(shù)據(jù)持久性有高度地設(shè)備具體性,每一種設(shè)備都有自己的用戶界面、輸入機(jī)制和數(shù)據(jù)存儲(chǔ)方法,這些往往不在配置所滿足的小要求的范圍之內(nèi)。
簡(jiǎn)表為相同消費(fèi)電子設(shè)備的不同的生產(chǎn)商提供了標(biāo)準(zhǔn)化的 Java類(lèi)庫(kù), 事實(shí)上,雖然配置規(guī)范的開(kāi)發(fā)由 Sun領(lǐng)導(dǎo),但是許多簡(jiǎn)表規(guī)范仍將繼續(xù)由特殊設(shè)備的供應(yīng)商領(lǐng)導(dǎo)。 比如說(shuō), Motorola領(lǐng)導(dǎo)了行動(dòng)電話和呼叫器簡(jiǎn)表規(guī)范的開(kāi)發(fā),又如 Palm 領(lǐng)導(dǎo) PDA簡(jiǎn)表的開(kāi)發(fā)。
現(xiàn)在,五個(gè)已知簡(jiǎn)表已經(jīng)有了規(guī)范, 記住,每個(gè)簡(jiǎn)表的責(zé)任都是為了完善配置的不足,下表列出了這五個(gè)簡(jiǎn)表:
簡(jiǎn) 表 完善配置
Mobile information devices profile (MIDP) 移動(dòng)電話和呼叫器 CLDC
Personal digital assistant profile Palm和Handspring的PDA 設(shè)備 CLDC
Foundation profile 用于所有不需要GUI的CDC設(shè)備的標(biāo)準(zhǔn)簡(jiǎn)表 CDC
Personal profile 替代PersonalJava的Foundation完善的簡(jiǎn)表 CDC
RMI profile 提供RMI的Foundation完善的簡(jiǎn)表 CDC
現(xiàn)在我想談一談另一個(gè)Java類(lèi)庫(kù)集,它現(xiàn)在差不多可以被認(rèn)為是另一個(gè)簡(jiǎn)表了。當(dāng)Sun為Palm開(kāi)發(fā)個(gè)KVM時(shí),他們需要一組類(lèi)來(lái) 開(kāi)發(fā)Palm的演示程序。這套類(lèi)庫(kù)被封裝進(jìn) com.sun.kjava程序包, 在 CLDC早期的開(kāi)發(fā)中,這些類(lèi)被廣泛的使用來(lái)測(cè)試和演示 J2ME。因?yàn)?kjava是的允許應(yīng)用程序開(kāi)發(fā)者使用 J2ME和 KVM開(kāi)發(fā)應(yīng)用程序的類(lèi),所以它就被廣泛使用了。甚至到了今天,一個(gè)用于 PDA或更特殊一點(diǎn)的 Palm的簡(jiǎn)表多已經(jīng)在開(kāi)發(fā)中,許多開(kāi)發(fā)者仍然希望使用 kjava類(lèi)來(lái)開(kāi)發(fā) PDA應(yīng)用程序。盡管 kjava類(lèi)不被支持,并且僅僅用于設(shè)計(jì)測(cè)試程序或演示程序,并且它們將被一個(gè)即將到來(lái)的簡(jiǎn)表所替代,但是開(kāi)發(fā)者們?nèi)匀粺嶂杂谑褂盟鼇?lái)開(kāi)發(fā)。
MIDP
Mobile Information Device Profile(移動(dòng)信息設(shè)備簡(jiǎn)表 ,簡(jiǎn)稱 MIDP ),個(gè)實(shí)現(xiàn)的簡(jiǎn)表,補(bǔ)充了 CLDC并且提供應(yīng)用程序語(yǔ)義和控件、用戶界面、持久存儲(chǔ)器、網(wǎng)絡(luò)和用于移動(dòng)電話的計(jì)時(shí)器、雙通道呼叫器和其他無(wú)線電設(shè)備。 因?yàn)?MIDP和 CLDC兩者都有引用實(shí)現(xiàn),我們可以使用一個(gè)例程來(lái)研究一下這個(gè)簡(jiǎn)表。
下面的例子是一個(gè)允許用戶輸入代表想知道的基金報(bào)價(jià)的代號(hào)的例子。應(yīng)用程序然后通過(guò) HTTP接到一個(gè)金融網(wǎng)站,獲得基金報(bào)價(jià),把價(jià)格儲(chǔ)存在一個(gè)數(shù)據(jù)庫(kù),然后把價(jià)格返回給用戶。
// 到如需要的J2ME類(lèi)
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.rms.*;
// 擴(kuò)展MIDlet類(lèi)來(lái)構(gòu)建我們的自定義MIDlet
public class FundTracker extends MIDlet implements
CommandListener {
file://顯示管理者變量
private Display display = null;
file://MIDlet的表單變量
private RequestForm reqForm = null;
file://MIDlet構(gòu)建器
public FundTracker () {
display = Display.getDisplay(this);
reqForm = new RequestForm("Fund Tracker");
reqForm.initForm();
reqForm.setCommandListener(this);
}
file://開(kāi)始 MIDlet 應(yīng)用程序
protected void startApp() {
display.setCurrent(reqForm);
}
file://暫停 Midlet
protected void pauseApp() {
}
file://銷(xiāo)毀Midlet
protected void destroyApp(boolean unconditional) {
}
file://通過(guò)監(jiān)聽(tīng)者響應(yīng)命令
public void commandAction(Command c, Displayable s) {
if (c == reqForm.getExitCommand()) {
destroyApp(false);
notifyDestroyed();
return;
}
if ((c == reqForm.getGetCommand()) &&
(reqForm.getSymField().getString().length() > 0)) {
getAndDisplayQuote();
} else
{
reqForm.getMsgString().setText("Symbol required");
}
}
file://儲(chǔ)存由#分開(kāi)的成對(duì)的基金字符串和報(bào)價(jià)字符串
private void storeQuote (String fund, String newQuote) {
file://數(shù)據(jù)庫(kù)變量
RecordStore quoteDB = null;
try {
quoteDB = RecordStore.openRecordStore(
"FundQuotes", true);
byte[] data = (fund + "#" + newQuote).getBytes();
int size = data.length;
quoteDB.addRecord(data, 0, size);
quoteDB.closeRecordStore();
}
catch (Exception recordException) {
System.out.println("Unable to store quote and/or
use Fund Quote database.");
}
}
file://通過(guò)QuoteService類(lèi)取回提交的代號(hào)表示的基金報(bào)價(jià)
private void getAndDisplayQuote(){
String fundSymbol = reqForm.getSymField().getString();
if (fundSymbol.length() > 0) {
String theQuote = QuoteService.getQuote(fundSymbol);
if (theQuote != null) {
storeQuote(fundSymbol, theQuote);
reqForm.getMsgString().setText(theQuote);
}
else
reqForm.getMsgString().setText("No quote" +
'\n' + "Check Symbol");
}
}
}
MIDP應(yīng)用程序稱為 MIDlet, 為了創(chuàng)建一個(gè) MIDlet,你必須寫(xiě)一個(gè)擴(kuò)展基本 MIDlet類(lèi)的類(lèi) (就像我們?cè)谏厦娲a段中列出的那樣)。 這有點(diǎn)類(lèi)似常見(jiàn)的 applet或 servlet。 MIDlets獨(dú)有的東西是把多個(gè) MIDlet組成一個(gè) MIDlet套件的能力。 這就允許 MIDlet在一個(gè)單獨(dú)的 JVM環(huán)境中共享資源,比如一個(gè)數(shù)據(jù)庫(kù)等等。 事實(shí)上,我們上面給出的例子還包括一個(gè) MIDlet ( RetrieveQuote,見(jiàn)上段程序),用于取回所報(bào)價(jià)格。 當(dāng)MIDlet被請(qǐng)求時(shí), MIDlet通過(guò)構(gòu)造程序?qū)嵗缓笳{(diào)用實(shí)例的 startApp()方法。
在 FundTracker例子中, MIDlet的用戶界面或顯示是由 Display類(lèi)的一個(gè)實(shí)例管理的。 對(duì)于每個(gè) MIDlet,只有一個(gè)顯示管理器實(shí)例。 所有可以顯示的項(xiàng)目,像屏幕或畫(huà)布(canvas),通過(guò)這個(gè)管理器都能夠成為可見(jiàn)的。因?yàn)樾袆?dòng)電話和呼叫器能力的多樣化,又因?yàn)橛糜谶@些設(shè)備的應(yīng)用程序類(lèi)型的差異, MIDP規(guī)范提供了兩種類(lèi)型的用戶界面。一個(gè)可移植性稍差、明確設(shè)備、低水平的應(yīng)用程序接口,允許圖形元素精確的控制和放置。 這個(gè)接口類(lèi)型是用于應(yīng)用程序特性比較典型的設(shè)備特別設(shè)計(jì)的,比如電子游戲。 一個(gè)可移植性稍好的、抽象的、的 GUI應(yīng)用程序接口,提供來(lái)用于商業(yè)應(yīng)用程序。
我們的例程使用的是的應(yīng)用程序接口和典型的用戶界面組件 (文本框,列表等等 ),是這類(lèi)界面通用的。比如說(shuō),實(shí)際的表單和所有的小組件在一個(gè)單獨(dú)的文件中都已定義。 就像在代碼段一中列出的那樣,當(dāng) MIDlet創(chuàng)建時(shí),一個(gè)表單的實(shí)例與 MIDlet關(guān)聯(lián)。 在調(diào)用 MIDlet startApp()方法的時(shí)候,通過(guò) Display對(duì)象顯示表單。 使用一個(gè)用于表單的類(lèi),允許我們?cè)谖覀兒?jiǎn)單的報(bào)價(jià)檢索應(yīng)用程序中重新使用這個(gè)表單 ( RetrieveQuote )。為了清晰性和風(fēng)格,我們通過(guò)一個(gè)單獨(dú)的類(lèi)來(lái)定義報(bào)價(jià)服務(wù)。 為了演示一般連接器結(jié)構(gòu)的能力,我們的報(bào)價(jià)服務(wù)類(lèi)通過(guò)一個(gè) Connector實(shí)例取回報(bào)價(jià)。
MIDP要求平臺(tái)設(shè)備提供一個(gè)機(jī)制用來(lái)儲(chǔ)存簡(jiǎn)單的數(shù)據(jù)記錄,通過(guò)正常的平臺(tái)事件,比如重新啟動(dòng)和電池更新維護(hù)系統(tǒng)的完整性。 MIDP稱一個(gè)持久數(shù)據(jù)庫(kù)為 RecordStore。 在我們的示例中, MIDlet打開(kāi)并添加一條記錄到 " MutualFundQuotes " RecordStore。 正如我們的演示程序,能添加到 RecordStore中的一種類(lèi)型的記錄是字節(jié)數(shù)組。 相同的 RecordStore是一個(gè)資源,它可以通過(guò)套件共享。 根據(jù) MIDP規(guī)范, 當(dāng) MIDlet從平臺(tái)中刪除后,RecordStore也會(huì)被從平臺(tái)中刪除。
PDA簡(jiǎn)表
Palm公司是開(kāi)發(fā)PDA簡(jiǎn)表規(guī)范的領(lǐng)頭人, 這個(gè)簡(jiǎn)表也是完善了 CLDC,在相當(dāng)長(zhǎng)的一段時(shí)間內(nèi),它都將是 kjava類(lèi)程序包的替代品。 Java規(guī)范建議這個(gè) profile至少應(yīng)當(dāng)提供兩個(gè)核心功能片段: 一個(gè)用戶界面顯示工具包,適合于 "有限的尺寸和深度顯示 "和一個(gè)持久數(shù)據(jù)存儲(chǔ)器機(jī)制。 顯示工具包應(yīng)該是抽象窗口工具包的一個(gè)子集, 而持久機(jī)制將為應(yīng)用程序、數(shù)據(jù)、配置/環(huán)境信息提供簡(jiǎn)單的數(shù)據(jù)存儲(chǔ)。
Foundation簡(jiǎn)表
下面三種簡(jiǎn)表不是非常常見(jiàn), 這三種簡(jiǎn)表的職責(zé)都是為了完善 CDC。 Personal和 RMI簡(jiǎn)表實(shí)際上是 Foundation簡(jiǎn)表的擴(kuò)展。 Foundation簡(jiǎn)表的任務(wù)是擔(dān)任一個(gè)基礎(chǔ)簡(jiǎn)表,便于以后開(kāi)發(fā)出來(lái)的提供圖形用戶接口、 網(wǎng)絡(luò)等功能的簡(jiǎn)表附著在它之上。 除了用于基礎(chǔ)簡(jiǎn)表, Foundation簡(jiǎn)表還提供完整網(wǎng)絡(luò)的支持,不管有沒(méi)有使用圖形用戶接口。
Personal簡(jiǎn)表
在當(dāng)前的規(guī)范需求下, Personal簡(jiǎn)表提供下一代 PersonalJava環(huán)境。這個(gè)簡(jiǎn)表允諾,提供互聯(lián)網(wǎng)連接性和 Web保真度以及一個(gè)能夠運(yùn)行 Java applets的 GUI。
RMI簡(jiǎn)表
回想一下 CDC配置為共享的、固定網(wǎng)絡(luò)連接信息設(shè)備提供小的 Java環(huán)境。 RMI簡(jiǎn)表將通過(guò)提供 Java到 Java的RMI來(lái)協(xié)助提供更好的網(wǎng)絡(luò)連接性。 通過(guò)使用 J2SE ( 1.2.x或更高版本的 ) RMI,這個(gè)簡(jiǎn)表將允許這些網(wǎng)絡(luò)設(shè)備與其他系統(tǒng)應(yīng)用程序交互操作 (這個(gè)系統(tǒng)不必也運(yùn)行 J2ME )。
kjava類(lèi)
正如前面提到的那樣, kjava類(lèi)是初提供的一個(gè)供測(cè)試用的類(lèi),在 Palm設(shè)備上運(yùn)行早期的 KVM和配置版本。 它們將被 PDA簡(jiǎn)表代替。 kjava類(lèi)擴(kuò)展了 CLDC并且提供一個(gè)圖形用戶接口、 Palm數(shù)據(jù)庫(kù)訪問(wèn),簡(jiǎn)單集合類(lèi)和一個(gè)三角法計(jì)算器。
在代碼段2中,我使用 com.sun.kjava重寫(xiě)了 MIDP FundTracker程序,讓它在 Palm上工作。 和前面的程序一樣,這個(gè)簡(jiǎn)單的程序允許用戶輸入一個(gè)公基金代號(hào)并從WWW上的金融報(bào)價(jià)服務(wù)商那里取回報(bào)價(jià)。
kjava應(yīng)用程序被稱作 spotlet。 事實(shí)上,一個(gè)應(yīng)用程序可以由很多 spotlet組成,但是在任何時(shí)間只有一個(gè) spotlet可以顯示在 Palm屏幕上。 在我們的例子中,我們創(chuàng)建一個(gè)基本 spotlet-- RequestFormSpotlet.java,為我們的兩個(gè) spotlets子類(lèi)提供用戶界面。代碼段 2擴(kuò)展了基本的 RequestFormSpotlet以便得到并儲(chǔ)存一個(gè)報(bào)價(jià)。 RetrieveSpotlet也擴(kuò)展了基本 RequestFormSpotlet并允許儲(chǔ)存的報(bào)價(jià)被取回(見(jiàn)圖)
代碼段2
import com.sun.kjava.*;
public final class FundSpotlet extends RequestFormSpotlet {
public static void main (String args[]) {
new FundSpotlet().draw();
}
private void draw() {
initForm();
setTitle("Fund Quote Requested");
}
public void penDown(int x, int y){
if (getExitButton().pressed(x,y)){
getGraphic().playSound(Graphics.SOUND_CONFIRMATION);
System.exit(0);
}
if (getSymField().pressed(x,y))
getSymField().setFocus();
if (getGetButton().pressed(x,y)) {
quoteRequested();
}
}
private void storeQuote (String fund, String newQuote) {
int dbType = 0x46554e44;
int dbCreator = 0x43415454;
com.sun.kjava.Database quoteDB;
try {
quoteDB = new com.sun.kjava.Database(dbType,
dbCreator, com.sun.kjava.Database.READWRITE);
if (!quoteDB .isOpen()) {
com.sun.kjava.Database.create(0, "MutualFundQuotes",
dbCreator, dbType, false);
quoteDB = new com.sun.kjava.Database(dbType,
dbCreator, com.sun.kjava.Database.READWRITE);
}
byte[] data = (fund + "#" + newQuote).getBytes();
quoteDB.addRecord(data);
quoteDB.close();
}
catch (Exception recordException) {
System.out.println("Unable to store quote and/or use
Mutual Fund Quote database.");
}
}
private void getAndDisplayQuote() {
String fundSymbol = getSymField().getText();
if (fundSymbol.length() > 0) {
String theQuote = QuoteService.getQuote(fundSymbol);
if (theQuote != null) {
storeQuote(fundSymbol, theQuote);
message(theQuote);
}
else
message("No quote. Check Symbol");
}
}
private void quoteRequested() {
message("");
getGraphic().playSound(Graphics.SOUND_STARTUP);
if ((getSymField().getText().length() > 0)) {
getAndDisplayQuote();
} else
{
message("Symbol required!");
}
}
}
在 RequestFormSpotlet程序中,類(lèi)似于 MIDP中的 Display對(duì)象,單獨(dú)的 Graphics管理許多 spotlet用戶界面顯示。它考慮到了屏幕會(huì)被清除,顯示邊界會(huì)被建立。 不象 MIDlet,沒(méi)有屏幕或畫(huà)布對(duì)象來(lái)讓我們添加用戶界面小組件, 取而代之的是按鈕、文本字段等等,直接描畫(huà)在 spotlet上。 paint()方法利用圖形環(huán)境從的 Graphics在屏幕上顯示小組件。
我們的MIDP程序的 QuoteService類(lèi)的大部分可以重新使用。 因?yàn)?kjava沒(méi)有象 MIDP中HttpConnection這樣特定的連接器界面,所以我們必須利用更多標(biāo)準(zhǔn)的一般的連接器結(jié)構(gòu)表單獲取 HTTP鏈接。 為了做到這一點(diǎn),使用代碼段 3中的代碼替換 getQuotePage()方法。注意注意使用 Connector,就像在 MIDP中我們使用 HttpConnection一樣。
代碼段3
private static String getQuotePage(String symbolString) {
StringBuffer quotePage = new StringBuffer();
int ch;
try {
InputStream in = Connector.openInputStream (
"testhttp://someurl/some_application?page=++&mode=fund&symbol="+
symbolString);
while ((ch = in.read()) > 0) {
quotePage.append((char)ch);
}
in.close();
return quotePage.toString();
} catch (IOException ex) {
System.out.println("Exception reading quote from
HTTP Connection");
return null;
}
}
Palm設(shè)備廣泛利用數(shù)據(jù)庫(kù), 你的 Palm中的通訊簿、備忘錄和記事本應(yīng)用程序都與數(shù)據(jù)庫(kù)有關(guān)。 kjava程序包提供了一個(gè)非常小的 Database類(lèi),不僅可以創(chuàng)建并保持應(yīng)用程序數(shù)據(jù),而且可以訪問(wèn)現(xiàn)有的數(shù)據(jù)庫(kù)。 如果你熟悉 Palm數(shù)據(jù)庫(kù),你可能會(huì)對(duì) kjava Database類(lèi)提供的功能和信息感到失望。 然而,請(qǐng)?jiān)俅斡涀。?kjava只是一個(gè)演示的版本。
在我們的例子中,我們的 spotlet訪問(wèn)一個(gè) Palm數(shù)據(jù)庫(kù) (如果不存在的話,則創(chuàng)建一個(gè)新的數(shù)據(jù)庫(kù))來(lái)儲(chǔ)存公基金報(bào)價(jià)。每個(gè) Palm數(shù)據(jù)庫(kù)都必須有名字、創(chuàng)建者 ID (一個(gè) Palm登記的的標(biāo)識(shí)號(hào) ) 和一個(gè)指定到某個(gè)單獨(dú)應(yīng)用程序的類(lèi)型號(hào)。 試圖打開(kāi)數(shù)據(jù)庫(kù)要通過(guò)嘗試創(chuàng)建一個(gè)帶有 ID信息的數(shù)據(jù)庫(kù)實(shí)例來(lái)實(shí)現(xiàn)。 就象 MIDP RecordStore,記錄被添加進(jìn) kjava數(shù)據(jù)庫(kù),通過(guò)把一個(gè)字節(jié)數(shù)組當(dāng)成記錄添加到數(shù)據(jù)庫(kù)中的形式。
五、J2ME規(guī)范
在 J2ME內(nèi)還有很多子規(guī)范, J2ME的重要的部分如下:PersonalJava、K虛擬機(jī) (KVM)、Java嵌入服務(wù)器以及 PersonalJava的兩個(gè)擴(kuò)展規(guī)范: JavaPhone和 JavaTV應(yīng)用程序接口。 你可以想象, JavaPhone是一個(gè)定位于無(wú)線電智能電話和互聯(lián)網(wǎng)絡(luò)可視電話的應(yīng)用程序接口,而 JavaTV則滿足機(jī)頂盒市場(chǎng)的需求。
下面我想詳細(xì)的談一談以上的規(guī)范:
1、PersonalJava
PersonalJava應(yīng)用程序環(huán)境目標(biāo)是 Web連接消費(fèi)設(shè)備----常常執(zhí)行來(lái)自網(wǎng)絡(luò)的小應(yīng)用程序。問(wèn)題是 PersonalJava如何適合 J2ME的配置和簡(jiǎn)表方案。 答案是 PersonalJava將被包容進(jìn) Connected Device Configuration中,終將被定義為 Personal簡(jiǎn)表,即前面所談到的Personal簡(jiǎn)表。
另一方面,有一段時(shí)間將有兩個(gè) Java應(yīng)用程序接口為嵌入開(kāi)發(fā)世界服務(wù): PersonalJava和 EmbeddedJava。 PersonalJava偎依在 J2ME大傘之下, 可為什么 EmbeddedJava不呢? EmbeddedJava不和 PersonalJava同在 J2ME內(nèi),是因?yàn)樵?PersonalJava和 EmbeddedJava應(yīng)用程序之間有一個(gè)基本的差別。 PersonalJava應(yīng)用程序期望連接到某類(lèi)網(wǎng)絡(luò)中下載并執(zhí)行小應(yīng)用程序。 按照這種觀點(diǎn), PersonalJava設(shè)備就是一般用途的消費(fèi)設(shè)備; 它們的能力可以被擴(kuò)展。
相比之下, EmbeddedJava設(shè)備則慘了點(diǎn)。 它們執(zhí)行的功能都非常具體的,基本沒(méi)有必要提供下載新的代碼到 EmbeddedJava設(shè)備的能力。 Hence, PersonalJava設(shè)備使用可擴(kuò)展 Java應(yīng)用程序接口; 而EmbeddedJava設(shè)備則沒(méi)有,因?yàn)闆](méi)有必要使用。
PersonalJava可以以兩種形式得到: 由原碼形式的,提供給那些對(duì)把PersonalJava移植到其他設(shè)備感興趣的開(kāi)發(fā)者,那些已經(jīng)把 PersonalJava移植到某個(gè)具體的操作系統(tǒng)和處理機(jī)的組織提供二進(jìn)制形式的 PersonalJava環(huán)境。有興趣探索 PersonalJava的開(kāi)發(fā)者如果沒(méi)有二進(jìn)制平臺(tái)也可以使用 PersonalJava模擬環(huán)境 ( PJEE )。 這個(gè)模擬器運(yùn)行于 Solaris/SPARC或 Windows,并且在許多配置中可用。 這些多種多樣的配置基于“ look and feel”和類(lèi)庫(kù)支持 (環(huán)境是否提供 PersonalJava規(guī)范中規(guī)定的限度的或的類(lèi)庫(kù))。PJEE包括類(lèi)文件,一個(gè)應(yīng)用程序 launcher和一個(gè) appletviewer (兩者都是為了調(diào)試功能并使其化)和其它的附帶的文件 (例如字體敘述文件)。
J2ME家族的另一位成員 JavaCheck實(shí)用程序,提供了 PersonalJava的補(bǔ)充支持。 你把應(yīng)用程序傳過(guò) JavaCheck,它將告訴你你的應(yīng)用程序在一個(gè) PersonalJava環(huán)境中能否順利地執(zhí)行。 JavaCheck檢查類(lèi)之間的依賴關(guān)系,如果應(yīng)用程序調(diào)用了一個(gè)在 PersonalJava不可用的應(yīng)用程序接口,它就會(huì)給出一個(gè)警報(bào)信號(hào)。 (據(jù)我所知,目前有兩種JavaCheck的版本可用,一個(gè)是用于檢驗(yàn) PersonalJava 1.0版應(yīng)用程序,另一個(gè)用于檢驗(yàn) 1.1.x版程序。 當(dāng)前的 PersonalJava應(yīng)用程序接口規(guī)范是 1.2,用于這一版本的 JavaCheck還沒(méi)有。 讀者請(qǐng)去Sun相關(guān)網(wǎng)站去看看( http : file://java.sun.com/products/personaljava)。
2、KVM
前面我也說(shuō)過(guò),KVM是用于 J2ME平臺(tái)小的虛擬機(jī),并且是用于CLDC配置的虛擬機(jī)。可是J2ME應(yīng)用程序并不一定非要使用 KVM,J2ME技術(shù)可以使用任何虛擬機(jī),不過(guò)至少應(yīng)當(dāng)有 KVM這樣的功能。
為了滿足基于KVM的設(shè)備一般只有狹小的內(nèi)存空間和有限的處理能力的事實(shí), KVM使用 C編寫(xiě) (它不是現(xiàn)有的VM改進(jìn)了的以后的產(chǎn)品)。 此外, KVM是模塊化的, 也就是說(shuō),它是由模塊構(gòu)建的,當(dāng)某個(gè)模塊實(shí)現(xiàn)了預(yù)先設(shè)定的目標(biāo)后,就可以很容易地把這一模塊卸載。 可選的某塊包括: 大的數(shù)據(jù)類(lèi)型 ( long、 float和 double ),多維數(shù)組、類(lèi)文件驗(yàn)證等。
KVM的本地界面以輕便性為原則構(gòu)建,所以在KVM中任務(wù)切換不依賴硬件產(chǎn)生的記時(shí)器中斷,因此在這種意思上來(lái)說(shuō)不是搶先式。任務(wù)切換發(fā)生在虛擬機(jī)執(zhí)行了一個(gè)預(yù)設(shè)編號(hào)的字節(jié)碼之后。 并且, KVM的無(wú)用單元收集利用一個(gè)標(biāo)記清掃(mark and sweep)算法來(lái)實(shí)現(xiàn)無(wú)用單元釋放。 因此,對(duì)象引用是直接的,就像標(biāo)準(zhǔn) Java一樣。
當(dāng)然,除了虛擬機(jī)以外還有許多可用的執(zhí)行環(huán)境,在小型設(shè)備中,虛擬機(jī)必須要么被擴(kuò)展,要么在附加工具協(xié)助下提供一個(gè)更加完整的運(yùn)行期環(huán)境,正是這個(gè)原因, KVM需要附帶的工具,比如說(shuō), JavaCodeCompact工具提供了預(yù)鏈接和預(yù)加載類(lèi), 允許Java類(lèi)被直接地鏈接進(jìn)虛擬機(jī)中。((設(shè)備上所有的應(yīng)用程序使用的類(lèi) can直接地嵌入虛擬機(jī)。)
KVM一個(gè)可選的附件就是 Java Application Manager ( Java應(yīng)用程序管理器,簡(jiǎn)稱 JAM )。JAM的工作就是處理下載、安裝、執(zhí)行和卸載 CLDC設(shè)備上的應(yīng)用程序的細(xì)節(jié)問(wèn)題,因?yàn)橘Y源有限,在CLDC設(shè)備上有可能不存在這些功能。JAM也處理更新安裝應(yīng)用程序的操作。(如果更新過(guò)程失敗,它甚至可以重新使用舊的應(yīng)用程序。 )
3、Java Embedded Server(Java嵌入服務(wù)器)
Java Embedded Server( Java嵌入服務(wù)器,簡(jiǎn)稱 JES),在 PersonalJava基礎(chǔ)上建立,是一個(gè)用于嵌入式網(wǎng)絡(luò)設(shè)備的運(yùn)行期環(huán)境。為了理解 JES,你必須理解兩個(gè)核心概念:服務(wù)和服務(wù)空間結(jié)構(gòu)。后者是前者的容器。服務(wù)程序是運(yùn)行于一個(gè) JES服務(wù)器上的組件化程序;服務(wù)空間結(jié)構(gòu)是為服務(wù)程序提供生命周期 支持的環(huán)境。
技術(shù)上說(shuō),服務(wù)程序是界面的實(shí)現(xiàn),事實(shí)上,它是一個(gè)實(shí)現(xiàn)特定活動(dòng)的Java類(lèi)集合。比如說(shuō),假如把 JES配置為一個(gè)家庭的氣候控制系統(tǒng)的服務(wù)器,可以把從模數(shù)轉(zhuǎn)換器讀到的溫度數(shù)據(jù)放進(jìn)一個(gè)數(shù)據(jù)組件程序中。我就可以稱這個(gè)組件為ReadThermostats服務(wù)程序。
在 JES的領(lǐng)域,服務(wù)的封裝媒介稱為 bundle。簡(jiǎn)單地說(shuō),bundle就是一個(gè)帶有特殊內(nèi)容的JAR文件。服務(wù)程序和bundle之間有一對(duì)一關(guān)系,一個(gè)bundle帶有一個(gè)服務(wù)程序。服務(wù)程序和 bundle之間有一對(duì)一關(guān)系,一個(gè) bundle帶有一個(gè)服務(wù)程序。可這也不一定,一個(gè) bundle可以設(shè)置多個(gè)服務(wù)程序索引 (注意, JES提供的所有的核心服務(wù),每個(gè) bundle中只有一個(gè) )。
正如前面提到的那樣,服務(wù)空間的一項(xiàng)工作就是管理服務(wù)程序的生命周期,這個(gè)工作的很大的部分包括解決服務(wù)隸屬關(guān)系。bundle內(nèi)容的一個(gè)重要的部分是bundle服務(wù)的依賴信息。所以,當(dāng)服務(wù)空間打開(kāi)一個(gè)bundle安裝它的服務(wù)時(shí),服務(wù)空間就可以確定外部需要什么服務(wù)。而且,一個(gè)服務(wù)的依賴關(guān)系并不是靜止不變的,它們可以隨某些事件改變。比如說(shuō)當(dāng)服務(wù)程序更新時(shí)的變化就是一個(gè)很好的例子。一個(gè)服務(wù)的新的版本可以添加或去除依賴關(guān)系。服務(wù)空間跟蹤并解決這樣的動(dòng)態(tài)依賴關(guān)系。如果服務(wù)空間處理所有服務(wù)程序的生命周期,這就暗示了服務(wù)空間被賦予知曉一切的能力,那就是說(shuō),它能夠推論結(jié)構(gòu)、依賴、安裝的細(xì)微差別等所有它負(fù)責(zé)的服務(wù)。服務(wù)空間通過(guò)在 bundle內(nèi)伴隨服務(wù)的 Java代碼模塊處理一些任務(wù),這些模塊被稱作 wizard(向?qū)ВES向?qū)歉鶕?jù)它們完成的任務(wù)命名的:
Dependencies -向?qū)Ц嬖V調(diào)用者一個(gè)bundle依賴關(guān)系是什么。
Installer-向?qū)幚韇undle中服務(wù)的安裝和刪除操作。
Activator -向?qū)е廊绾螁?dòng)和終止服務(wù)。
Updater -向?qū)Э丶耣undle中的服務(wù)。(更新向?qū)Р粌H知道更新一個(gè)服務(wù),而且知道在何時(shí)和什么情況下更新服務(wù)。 )
About -這個(gè)向?qū)В拖袼Q意味的那樣,返回關(guān)于 bundle內(nèi)容的信息。
Dispatcher -這是一種元向?qū)В╩eta-wizard)。服務(wù)空間調(diào)用dispatcher向?qū)Фㄎ灰粋€(gè)bundle的其他向?qū)А?
當(dāng)一個(gè) JES服務(wù)器啟動(dòng)的時(shí)候,服務(wù)空間并不是完全沒(méi)有啟動(dòng)服務(wù)。JES定義一組核心服務(wù)(可選),這些都是任何 JES服務(wù)器的組成部分。這些核心服務(wù)包含:
HTTP服務(wù)
日志 -記錄錯(cuò)誤和事件日志
日期 -精確到秒的日期/時(shí)間服務(wù)
連接管理器 -提供網(wǎng)絡(luò)服務(wù)和Socket綁定,也處理連接接收。
線程管理器 -管理服務(wù)器提供的線程。thread管理器支持線程池并允許有效使用線程上界的規(guī)范。
計(jì)劃程序 -提供未來(lái)的事件計(jì)劃安排 (可用于告訴服務(wù)器某某動(dòng)作必須在某某事件發(fā)生 )
RMI
SNMP
控制臺(tái) -提供遠(yuǎn)程管理服務(wù)器功能
基于 HTTP的遠(yuǎn)程應(yīng)用程序接口實(shí)現(xiàn)
基于 RMI的遠(yuǎn)程應(yīng)用程序接口實(shí)現(xiàn)
如果你把服務(wù)空間結(jié)構(gòu)當(dāng)成 JavaBean中的容器的話, JES就變得容易理解了。在這種類(lèi)比關(guān)系中,服務(wù)程序就相當(dāng) JavaBean。那么,正象組件容器提供一個(gè)環(huán)境供 JavaBeans實(shí)例化、運(yùn)行一樣,服務(wù)空間就是以實(shí)例化的服務(wù)的聚集地。服務(wù)空間管理安裝、實(shí)例化、執(zhí)行、終止以及卸載服務(wù);它也提供應(yīng)用程序接口供服務(wù)交互作用。