一、J2ME概述
到目前為止,大部分人都已非常熟悉 Java 2平台,以及 Sun如何把 Java技術分成三個版本 (標准版、袖珍版以及企業版),Sun 在1999年6月時推出了 Java 2袖珍版 (J2ME)來滿足消費電子和嵌入設備的需要。J2ME是為了那些使用有限的能源、有限的網絡連接 (常常是無線連接)以及有限圖形用戶界面能力的設備開發的。它最初的目標是 16位或 32位處理器,16 MHz時鐘頻率, 512K或更少內存的設備。乍一看之下, J2ME就像一個沒有綁定明顯主題的松散的應用程序接口和技術規范。我們想通過說它不是什麼東西的方法來描述它,它不是一組用於台式機 Java應用程序規范,如果你再觀察仔細一些,你會發現所有的 J2ME組件都圍繞一個中心,這些中心被稱為configuration(配置 ,Sun的市場營銷資料也稱它們 design centers,設計中心),它們中間的每一個都是用於消費電子和嵌入設備的特別的類。
Connected limited device configuration(有限連接設備配置,簡稱 CLDC ) 這個配置定義了 Java應用程序接口以及支持手持設備的技術,就像 Sun的文檔中所描述的那樣, " devices that you hold in your hand(你握在手中的設備) " Palm序列手持設備可能是這一領域的設備的最好的例子,特別是它有開發 CLDC的功能以及 Palm設備運行期系統可用。
Connected device configuration(連接設備配置 CDC ) 這個配置定義支持象 Sun文檔中所說, " devices that you plug into plug into the wall(你插入牆的設備)的設備的應用程序接口和技術,這樣的設備的一個例子可能就是機頂盒。
這兩種配置不同的地方就在於它們應用於的裝置的能力, CLDC設備的處理器能力有限 (與台式機系統比較 ),並且存儲器大小一般也只在128 KB到 512 KB之間, 與此同時,CDC系統就不同了,它可能有 32位或 64位處理器,以及有限的存儲容量,不過它的下限也得超過512K。 它遵循的原則就是,每個不同的能力硬件的配置都將被不同的虛擬機支持。 基於 CDC的系統使用一個功能強勁的虛擬機,而基於 CLDC系統的使用 KVM 。
每個配置代表一種低水平的,基本的應用程序接口,在這兩個相似基礎之上是 profile(簡表),用於特殊設備的額外的應用程序接口。 我想通過看一張來自SUN提供的文檔中的圖表 (參見圖 1 )來解釋這其中的關系。
圖一解釋 配置和簡表的體系結構
J2ME的體系結構被橫向地分成三層,縱向分成兩部分。配置包括一個控制配置核心類的虛擬機, 具體的簡表位於每個配置之上。
J2ME現在定義兩個配置, Connected Device configuration(連接設備配置 CDC )和限制性更強的 Connected Limited Device Configuration (有限連接設備配置)。 簡表的實現是 Java應用程序接口的一個集合,用於適應被定義配置的應用程序接口提供的服務,簡表是一個完整的運行環境,一個在簡表上執行的應用程序不需要額外的支持類。
J2ME沒有定義滿足這兩種配置的標准化用戶接口,Sun也承認現在的消費設備多種多樣,用戶界面也各不一樣,所以定義一個可用於所有用戶的界面是一場失敗的戰爭。 J2ME中的用戶界面定義在簡表中。
二、J2ME的體系結構
現在個人計算機系統的數量和種類已經發展到無法控制的地步,請你想一想,你編寫的程序運行在“信息家電”舞台的情景吧,這些信息家電包括呼叫器,行動電話,像Palm這樣的個人數字助手(PDA),電視機頂盒,POS終端以及其他的消費電子設備。現在全世界上光是手提電話生產商就有許多,更不用說別的家電設備了,而且每一種家電設備又有不同的特性和界面。所以,你可以想到, Java應用程序的輕便性以及能夠解決開發這麼許多不同的設備程序的能力,使大家對J2ME有很大的期許。當然,為了更好的開發這些信息家電,就要求把Java的精髓壓縮進一個非常小的程序包中,這就是J2ME。
J2ME是一種通過許多部件和規范的技術, 這眾多的部件和規范幫助 J2ME來滿足這眾多的消費產品的不同的需要。和所有的爪哇程式語言技術一樣,在它的核心屬於一種虛擬機。 就像使用所有 Java技術一樣,J2ME的核心也在一種虛擬機中。 最初,用於 J2ME應用程序虛擬機的被稱作 Kilobyte virtual Machine或簡稱 KVM。就像它名稱的含義, KVM比較小,通常只有 128K或更少。這比起我們通常了解和使用的 Java 2標准版 Java虛擬機 ( JVM )的 32 MB來說就小得多了。
用於連接虛擬機的是一系列配置和簡表,它們提供了用於特定 J2ME環境的類應用程序接口(見圖二)。 每個配置和簡表處理一般或具體的消費產品,配置和簡表規范是由多種多樣的設備生產商和用戶共同開發並建立的。配置是用於一組通用設備的最小的 Java平台, 常常歸為一種橫向的設備分組,相對來說,橫向分組設備是那些共享相同的內存安排,通信帶寬,能量需求以及用戶能力的設備,一般認為配置能夠提供這眾多的設備的所有需求。
圖二解釋: J2ME層次
Java虛擬機是 J2ME技術的核心,但是配置和簡表提供特殊環境的類應用程序接口。配置是用於一組通用設備的最小的 Java平台,而簡表則為具體的設備家族或特別的應用程序提供更具體的能力。
J2ME領域的新的開發者常常被這些事實困惑的, 事實上, Sun的第一個配置(現在只是一種配置的引用實現 )帶有稱為 KVM的虛擬機引用實現, KVM滿足配置的虛擬機的必要條件。然而, Sun的 KVM也可以被另外一個虛擬機所代替,現在, 正是因為配置和虛擬機結合得有點緊密,因此導致了這麼多的混亂。
另一方面,簡表完善了 配置,為某個具體的設備家族或某個具體的工業片段應用程序提供更高的性能。 換言之, 簡表為具體的縱向市場的設備比如說行動電話提供更多的性能。這裡的關鍵就是 簡表必須完善 配置, 沒有 配置和虛擬機提供核心類應用程序接口和運行期環境的話,簡表也不會工作。
通常,簡表為一種給定的垂直分組設備提供用戶界面、輸入法、持久性機制。這類 簡表被認為是發展這些設備應用程序的完整的工具包。我們見到最多的應用程序簡表的例子就移動電話簡表和個人數字助手(PDA)簡表,其他簡表為范圍寬廣的設備提供非常特殊的功能或應用程序可移植性,這方面的例子就是提供遠程方法調用 ( RMI )功能的簡表和提供統一銀行事務的簡表。
虛擬機、 配置、 簡表…你是不是已經被搞迷糊了? 如果這樣的話,我們就來簡化一下 J2ME體系結構吧。 如果你想為小型信息家電編寫 Java應用程序的話,你就需要兩個前提:一個 配置和至少一個 簡表。 現在, 一般是配置捆綁了虛擬機和一套針對你的平台所能夠用的橫向分組設備的Java類庫。其次,你至少還需要一個 簡表來為你的平台提供附加的 Java類,這個 簡表通常會為你的設備提供用戶界面、輸入和數據庫類。有了這兩個前提,你就了使用 Java為你的設備編寫應用程序的基本的J2ME環境。
三、詳細談談J2ME配置
J2ME可以在好幾個不同的配置中進行配置。就像先前提到的,每個配置為一組通用設備提供最小的 Java平台,到目前為止,只有兩種配置規范。通過 Java規范定義的這兩種配置是 Connected Limited Device Configuration (有限連接設備配置, CLDC )和 Connected Device Configuration (連接設備配置 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.Net、 java.util和 Java.lang包,配置可能還要包括其他需要的程序包。
CLDC
CLDC起源可以追溯到1999年JavaOne大會上介紹的Sun的第一個袖珍版 Java和第一個 KVM以及相關的類庫,雖然 CLDC和所有的配置都滿足成為虛擬機的條件,可它本身還不是虛擬機,CLDC的引用實現只是包含在當前的分布中的 KVM。
根據規范中所說,運行 CLDC的設備應該有 512K或更少的內存空間、一個有限的電源供給 (通常是使用電池)、有限的或斷斷續續的網絡連接性 ( 9600 bps或更少 )以及多樣化的用戶界面甚至沒有用戶界面。 通常說來,這個配置是為個人化的、移動的、有限連接信息設備而設計,比如呼叫器、移動電話和 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類創建和打開五種不同類型的連接的方法:
HTTP Connector.open("http://www.xyz.com");
套接字 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基於 J2SE 1.3應用程序接口,包含所有定義在CLDC規范(包括 javax.microedition程序包)中的Java語言應用程序接口。與CLDC相比, CLDC所有缺少的特性和類在 CDC中都被補齊,包含映射、最終化、所有的錯誤處理類、浮點數、屬性、輸入/輸出 ( File、 FileInputStream等等 )和弱的引用。 一般說來, CDC中預期的類包括一個J2SE子集和一個完整的 CLDC超集,如圖4中所示:
圖4 :J2SE、CLDC和CDC的關系
就像使用所有的配置一樣,CDC有基層虛擬機的具體的必要條件。 根據 CDC規范,基層虛擬機必須提供實現完整的 Java虛擬機的支持 。 如果虛擬機實現有一個用於激活設備的本地方法的界面,它必須兼容 JNI 1.1版本。 如果虛擬機實現有一個調試界面,它必須兼容 Java虛擬機調試界面 ( JVMDI )規范。 如果虛擬機有一個簡表界面,它必須兼容 Java虛擬機簡表界面 ( JVMPI )規范。 可見,為了實現這些功能,CDC肯定會變得很大,就不能稱其為K虛擬機了,因此,我們通常稱用於CDC的虛擬機為 CVM,這裡的 C代表 compact、connected、consumer。
四、談談J2ME簡表
雖然配置為一組通用設備提供了最小的 Java平台,但是應用程序開發者感興趣的是為一個個別的設備生產應用程序,當他們只是使用配置的話,他們編寫的應用程序就會有一些欠缺。 配置必須滿足所有的設備的最小的要求, 用戶界面、輸入機制和數據持久性有高度地設備具體性,每一種設備都有自己的用戶界面、輸入機制和數據存儲方法,這些往往不在配置所滿足的最小要求的范圍之內。
簡表為相同消費電子設備的不同的生產商提供了標准化的 Java類庫, 事實上,雖然配置規范的開發由 Sun領導,但是許多簡表規范仍將繼續由特殊設備的供應商領導。 比如說, Motorola領導了行動電話和呼叫器簡表規范的開發,又如 Palm 領導 PDA簡表的開發。
現在,五個已知簡表已經有了規范, 記住,每個簡表的責任都是為了完善配置的不足,下表列出了這五個簡表:
簡 表 完善配置 Mobile information devices profile (MIDP) 移動電話和呼叫器 CLDC Personal digital assistant profile Palm和Handspring的PDA 設備 CLDC Foundation profile 用於所有不需要GUI的CDC設備的標准簡表 CDC Personal profile 替代PersonalJava的Foundation完善的簡表 CDC RMI profile 提供RMI的Foundation完善的簡表 CDC
現在我想談一談另一個Java類庫集,它現在差不多可以被認為是另一個簡表了。當Sun為Palm開發第一個KVM時,他們需要一組類來 開發Palm的演示程序。這套類庫被封裝進 com.sun.kjava程序包, 在 CLDC早期的開發中,這些類被廣泛的使用來測試和演示 J2ME。因為 kJava是唯一的允許應用程序開發者使用 J2ME和 KVM開發應用程序的類,所以它就被廣泛使用了。甚至到了今天,一個用於 PDA或更特殊一點的 Palm的簡表多已經在開發中,許多開發者仍然希望使用 kjava類來開發 PDA應用程序。盡管 kJava類不被支持,並且僅僅用於設計測試程序或演示程序,並且它們將被一個即將到來的簡表所替代,但是開發者們仍然熱衷於使用它來開發。
MIDP
Mobile Information Device Profile(移動信息設備簡表 ,簡稱 MIDP ),第一個實現的簡表,補充了 CLDC並且提供應用程序語義和控件、用戶界面、持久存儲器、網絡和用於移動電話的計時器、雙通道呼叫器和其他無線電設備。 因為 MIDP和 CLDC兩者都有引用實現,我們可以使用一個例程來研究一下這個簡表。
下面的例子是一個允許用戶輸入代表想知道的基金報價的代號的例子。應用程序然後通過 HTTP接到一個金融網站,獲得基金報價,把價格儲存在一個數據庫,然後把價格返回給用戶。
// 到如需要的J2ME類
import Javax.microedition.midlet.*;
import Javax.microedition.lcdui.*;
import Javax.microedition.rms.*;
// 擴展MIDlet類來構建我們的自定義MIDlet
public class FundTracker extends MIDlet implements
CommandListener {
file://顯示管理者變量
private Display display = null;
file://MIDlet的表單變量
private RequestForm reqForm = null;
file://MIDlet構建器
public FundTracker () {
display = Display.getDisplay(this);
reqForm = new RequestForm("Fund Tracker");
reqForm.initForm();
reqForm.setCommandListener(this);
}
file://開始 MIDlet 應用程序
protected void startApp() {
display.setCurrent(reqForm);
}
file://暫停 Midlet
protected void pauseApp() {
}
file://銷毀Midlet
protected void destroyApp(boolean unconditional) {
}
file://通過監聽者響應命令
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://儲存由#分開的成對的基金字符串和報價字符串
private void storeQuote (String fund, String newQuote) {
file://數據庫變量
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://通過QuoteService類取回提交的代號表示的基金報價
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應用程序稱為 MIDlet, 為了創建一個 MIDlet,你必須寫一個擴展基本 MIDlet類的類 (就像我們在上面代碼段中列出的那樣)。 這有點類似常見的 applet或 servlet。 MIDlets獨有的東西是把多個 MIDlet組成一個 MIDlet套件的能力。 這就允許 MIDlet在一個單獨的 JVM環境中共享資源,比如一個數據庫等等。 事實上,我們上面給出的例子還包括一個 MIDlet ( RetrIEveQuote,見上段程序),用於取回所報價格。 當MIDlet被請求時, MIDlet通過構造程序實例化,然後調用實例的 startApp()方法。
在 FundTracker例子中, MIDlet的用戶界面或顯示是由 Display類的一個實例管理的。 對於每個 MIDlet,只有一個顯示管理器實例。 所有可以顯示的項目,像屏幕或畫布(canvas),通過這個管理器都能夠成為可見的。因為行動電話和呼叫器能力的多樣化,又因為用於這些設備的應用程序類型的差異, MIDP規范提供了兩種類型的用戶界面。一個可移植性稍差、明確設備、低水平的應用程序接口,允許圖形元素精確的控制和放置。 這個接口類型是用於應用程序特性比較典型的設備特別設計的,比如電子游戲。 一個可移植性稍好的、抽象的、高級的 GUI應用程序接口,提供來用於商業應用程序。
我們的例程使用的是高級的應用程序接口和典型的用戶界面組件 (文本框,列表等等 ),是這類界面通用的。比如說,實際的表單和所有的小組件在一個單獨的文件中都已定義。 就像在代碼段一中列出的那樣,當 MIDlet創建時,一個表單的實例與 MIDlet關聯。 在調用 MIDlet startApp()方法的時候,通過 Display對象顯示表單。 使用一個用於表單的類,允許我們在我們簡單的報價檢索應用程序中重新使用這個表單 ( RetrIEveQuote )。為了清晰性和風格,我們通過一個單獨的類來定義報價服務。 為了演示一般連接器結構的能力,我們的報價服務類通過一個 Connector實例取回報價。
MIDP要求平台設備提供一個機制用來儲存簡單的數據記錄,通過正常的平台事件,比如重新啟動和電池更新維護系統的完整性。 MIDP稱一個持久數據庫為 RecordStore。 在我們的示例中, MIDlet打開並添加一條記錄到 " MutualFundQuotes " RecordStore。 正如我們的演示程序,能添加到 RecordStore中的唯一一種類型的記錄是字節數組。 相同的 RecordStore是一個資源,它可以通過套件共享。 根據 MIDP規范, 當 MIDlet從平台中刪除後,RecordStore也會被從平台中刪除。
PDA簡表
Palm公司是開發PDA簡表規范的領頭人, 這個簡表也是完善了 CLDC,在相當長的一段時間內,它都將是 kjava類程序包的替代品。 Java規范建議這個 profile至少應當提供兩個核心功能片段: 一個用戶界面顯示工具包,適合於 "有限的尺寸和深度顯示 "和一個持久數據存儲器機制。 顯示工具包應該是抽象窗口工具包的一個子集, 而持久機制將為應用程序、數據、配置/環境信息提供簡單的數據存儲。
Foundation簡表
下面三種簡表不是非常常見, 這三種簡表的職責都是為了完善 CDC。 Personal和 RMI簡表實際上是 Foundation簡表的擴展。 Foundation簡表的任務是擔任一個基礎簡表,便於以後開發出來的提供圖形用戶接口、 網絡等功能的簡表附著在它之上。 除了用於基礎簡表, Foundation簡表還提供完整網絡的支持,不管有沒有使用圖形用戶接口。
Personal簡表
在當前的規范需求下, Personal簡表提供下一代 PersonalJava環境。這個簡表允諾,提供互聯網連接性和 Web保真度以及一個能夠運行 Java applets的 GUI。
RMI簡表
回想一下 CDC配置為共享的、固定網絡連接信息設備提供最小的 Java環境。 RMI簡表將通過提供 Java到 Java的RMI來協助提供更好的網絡連接性。 通過使用 J2SE ( 1.2.x或更高版本的 ) RMI,這個簡表將允許這些網絡設備與其他系統應用程序交互操作 (這個系統不必也運行 J2ME )。
kJava類
正如前面提到的那樣, kjava類是最初提供的一個供測試用的類,在 Palm設備上運行早期的 KVM和配置版本。 它們將被 PDA簡表代替。 kJava類擴展了 CLDC並且提供一個圖形用戶接口、 Palm數據庫訪問,簡單集合類和一個三角法計算器。
在代碼段2中,我使用 com.sun.kJava重寫了 MIDP FundTracker程序,讓它在 Palm上工作。 和前面的程序一樣,這個簡單的程序允許用戶輸入一個公基金代號並從WWW上的金融報價服務商那裡取回報價。
kjava應用程序被稱作 spotlet。 事實上,一個應用程序可以由很多 spotlet組成,但是在任何時間只有一個 spotlet可以顯示在 Palm屏幕上。 在我們的例子中,我們創建一個基本 spotlet-- RequestFormSpotlet.Java,為我們的兩個 spotlets子類提供用戶界面。代碼段 2擴展了基本的 RequestFormSpotlet以便得到並儲存一個報價。 RetrIEveSpotlet也擴展了基本 RequestFormSpotlet並允許儲存的報價被取回(見圖)
代碼段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程序中,類似於 MIDP中的 Display對象,單獨的 Graphics管理許多 spotlet用戶界面顯示。它考慮到了屏幕會被清除,顯示邊界會被建立。 不象 MIDlet,沒有屏幕或畫布對象來讓我們添加用戶界面小組件, 取而代之的是按鈕、文本字段等等,直接描畫在 spotlet上。 paint()方法利用圖形環境從獨一無二的 Graphics在屏幕上顯示小組件。
我們的MIDP程序的 QuoteService類的大部分可以重新使用。 因為 kJava沒有象 MIDP中HttpConnection這樣特定的連接器界面,所以我們必須利用更多標准的一般的連接器結構表單獲取 HTTP鏈接。 為了做到這一點,使用代碼段 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設備廣泛利用數據庫, 你的 Palm中的通訊簿、備忘錄和記事本應用程序都與數據庫有關。 kjava程序包提供了一個非常小的 Database類,不僅可以創建並保持應用程序數據,而且可以訪問現有的數據庫。 如果你熟悉 Palm數據庫,你可能會對 kjava Database類提供的功能和信息感到失望。 然而,請再次記住, kJava只是一個演示的版本。
在我們的例子中,我們的 spotlet訪問一個 Palm數據庫 (如果不存在的話,則創建一個新的數據庫)來儲存公基金報價。每個 Palm數據庫都必須有名字、創建者 ID (一個 Palm登記的唯一的標識號 ) 和一個指定到某個單獨應用程序的類型號。 試圖打開數據庫要通過嘗試創建一個帶有 ID信息的數據庫實例來實現。 就象 MIDP RecordStore,記錄被添加進 kJava數據庫,通過把一個字節數組當成記錄添加到數據庫中的形式。
五、J2ME規范
在 J2ME內還有很多子規范, J2ME的重要的部分如下:PersonalJava、K虛擬機 (KVM)、Java嵌入服務器以及 PersonalJava的兩個擴展規范: JavaPhone和 JavaTV應用程序接口。 你可以想象, JavaPhone是一個定位於無線電智能電話和互聯網絡可視電話的應用程序接口,而 JavaTV則滿足機頂盒市場的需求。
下面我想詳細的談一談以上的規范:
1、PersonalJava
PersonalJava應用程序環境目標是 Web連接消費設備----常常執行來自網絡的小應用程序。問題是 PersonalJava如何適合 J2ME的配置和簡表方案。 答案是 PersonalJava將被包容進 Connected Device Configuration中,最終將被定義為 Personal簡表,即前面所談到的Personal簡表。
另一方面,有一段時間將有兩個 Java應用程序接口為嵌入開發世界服務: PersonalJava和 EmbeddedJava。 PersonalJava偎依在 J2ME大傘之下, 可為什麼 EmbeddedJava不呢? EmbeddedJava不和 PersonalJava同在 J2ME內,是因為在 PersonalJava和 EmbeddedJava應用程序之間有一個基本的差別。 PersonalJava應用程序期望連接到某類網絡中下載並執行小應用程序。 按照這種觀點, PersonalJava設備就是一般用途的消費設備; 它們的能力可以被擴展。
相比之下, EmbeddedJava設備則慘了點。 它們執行的功能都非常具體的,基本沒有必要提供下載新的代碼到 EmbeddedJava設備的能力。 Hence, PersonalJava設備使用可擴展 Java應用程序接口; 而EmbeddedJava設備則沒有,因為沒有必要使用。
PersonalJava可以以兩種形式得到: 由原碼形式的,提供給那些對把PersonalJava移植到其他設備感興趣的開發者,那些已經把 PersonalJava移植到某個具體的操作系統和處理機的組織提供二進制形式的 PersonalJava環境。有興趣探索 PersonalJava的開發者如果沒有二進制平台也可以使用 PersonalJava模擬環境 ( PJEE )。 這個模擬器運行於 Solaris/SPARC或 Windows,並且在許多配置中可用。 這些多種多樣的配置基於“ look and feel”和類庫支持 (環境是否提供 PersonalJava規范中規定的最低限度的或最大的類庫)。PJEE包括類文件,一個應用程序 launcher和一個 appletvIEwer (兩者都是為了調試功能並使其最優化)和其它的附帶的文件 (例如字體敘述文件)。
J2ME家族的另一位成員 JavaCheck實用程序,提供了 PersonalJava的補充支持。 你把應用程序傳過 JavaCheck,它將告訴你你的應用程序在一個 PersonalJava環境中能否順利地執行。 JavaCheck檢查類之間的依賴關系,如果應用程序調用了一個在 PersonalJava不可用的應用程序接口,它就會給出一個警報信號。 (據我所知,目前有兩種JavaCheck的版本可用,一個是用於檢驗 PersonalJava 1.0版應用程序,另一個用於檢驗 1.1.x版程序。 當前的 PersonalJava應用程序接口規范是 1.2,用於這一版本的 JavaCheck還沒有。
2、KVM
前面我也說過,KVM是用於 J2ME平台最小的虛擬機,並且是用於CLDC配置的虛擬機。可是J2ME應用程序並不一定非要使用 KVM,J2ME技術可以使用任何虛擬機,不過至少應當有 KVM這樣的功能。
為了滿足基於KVM的設備一般只有狹小的內存空間和有限的處理能力的事實, KVM使用 C編寫 (它不是現有的VM改進了的以後的產品)。 此外, KVM是模塊化的, 也就是說,它是由模塊構建的,當某個模塊實現了預先設定的目標後,就可以很容易地把這一模塊卸載。 可選的某塊包括: 大的數據類型 ( long、 float和 double ),多維數組、類文件驗證等。
KVM的本地界面以輕便性為原則構建,所以在KVM中任務切換不依賴硬件產生的記時器中斷,因此在這種意思上來說不是搶先式。任務切換發生在虛擬機執行了一個預設編號的字節碼之後。 並且, KVM的無用單元收集利用一個標記清掃(mark and sweep)算法來實現無用單元釋放。 因此,對象引用是直接的,就像標准 Java一樣。
當然,除了虛擬機以外還有許多可用的執行環境,在小型設備中,虛擬機必須要麼被擴展,要麼在附加工具協助下提供一個更加完整的運行期環境,正是這個原因, KVM需要附帶的工具,比如說, JavaCodeCompact工具提供了預鏈接和預加載類, 允許Java類被直接地鏈接進虛擬機中。((設備上所有的應用程序使用的類 can直接地嵌入虛擬機。)
KVM一個可選的附件就是 Java Application Manager ( Java應用程序管理器,簡稱 JAM )。JAM的工作就是處理下載、安裝、執行和卸載 CLDC設備上的應用程序的細節問題,因為資源有限,在CLDC設備上有可能不存在這些功能。JAM也處理更新安裝應用程序的操作。(如果更新過程失敗,它甚至可以重新使用舊的應用程序。 )
3、Java Embedded Server(Java嵌入服務器)
Java Embedded Server( Java嵌入服務器,簡稱 JES),在 PersonalJava基礎上建立,是一個用於嵌入式網絡設備的運行期環境。為了理解 JES,你必須理解兩個核心概念:服務和服務空間結構。後者是前者的容器。服務程序是運行於一個 JES服務器上的組件化程序;服務空間結構是為服務程序提供生命周期 支持的環境。
技術上說,服務程序是界面的實現,事實上,它是一個實現特定活動的Java類集合。比如說,假如把 JES配置為一個家庭的氣候控制系統的服務器,可以把從模數轉換器讀到的溫度數據放進一個數據組件程序中。我就可以稱這個組件為ReadThermostats服務程序。
在 JES的領域,服務的封裝媒介稱為 bundle。簡單地說,bundle就是一個帶有特殊內容的JAR文件。服務程序和bundle之間有一對一關系,一個bundle帶有一個服務程序。服務程序和 bundle之間有一對一關系,一個 bundle帶有一個服務程序。可這也不一定,一個 bundle可以設置多個服務程序索引 (注意, JES提供的所有的核心服務,每個 bundle中只有一個 )。
正如前面提到的那樣,服務空間的一項工作就是管理服務程序的生命周期,這個工作的很大的部分包括解決服務隸屬關系。bundle內容的一個重要的部分是bundle服務的依賴信息。所以,當服務空間打開一個bundle安裝它的服務時,服務空間就可以確定外部需要什麼服務。而且,一個服務的依賴關系並不是靜止不變的,它們可以隨某些事件改變。比如說當服務程序更新時的變化就是一個很好的例子。一個服務的新的版本可以添加或去除依賴關系。服務空間跟蹤並解決這樣的動態依賴關系。如果服務空間處理所有服務程序的生命周期,這就暗示了服務空間被賦予知曉一切的能力,那就是說,它能夠推論結構、依賴、安裝的細微差別等所有它負責的服務。服務空間通過在 bundle內伴隨服務的 Java代碼模塊處理一些任務,這些模塊被稱作 wizard(向導)。JES向導是根據它們完成的任務命名的:
DependencIEs -向導告訴調用者一個bundle依賴關系是什麼。
Installer-向導處理bundle中服務的安裝和刪除操作。
Activator -向導知道如何啟動和終止服務。
Updater -向導控件更新bundle中的服務。(更新向導不僅知道更新一個服務,而且知道在何時和什麼情況下更新服務。 )
About -這個向導,就像它名稱意味的那樣,返回關於 bundle內容的信息。
Dispatcher -這是一種元向導(meta-wizard)。服務空間調用dispatcher向導定位一個bundle的其他向導。
當一個 JES服務器啟動的時候,服務空間並不是完全沒有啟動服務。JES定義一組核心服務(可選),這些都是任何 JES服務器的組成部分。這些核心服務包含:
HTTP服務
日志 -記錄錯誤和事件日志
日期 -精確到秒的日期/時間服務
連接管理器 -提供網絡服務和Socket綁定,也處理連接接收。
線程管理器 -管理服務器提供的線程。thread管理器支持線程池並允許有效使用線程上界的規范。
計劃程序 -提供未來的事件計劃安排 (可用於告訴服務器某某動作必須在某某事件發生 )
RMI
SNMP
控制台 -提供遠程管理服務器功能
基於 HTTP的遠程應用程序接口實現
基於 RMI的遠程應用程序接口實現
如果你把服務空間結構當成 JavaBean中的容器的話, JES就變得容易理解了。在這種類比關系中,服務程序就相當 JavaBean。那麼,正象組件容器提供一個環境供 JavaBeans實例化、運行一樣,服務空間就是以實例化的服務的聚集地。服務空間管理安裝、實例化、執行、終止以及卸載服務;它也提供應用程序接口供服務交互作用。