摘要:本文是J2ME開發的入門性文章,從零開始介紹了進行J2ME開發首先需要了解的一些東西。閱讀本文幾乎不需要相關的基礎知識。
1.1. J2ME簡介
J2ME是Java 2 Platform, Micro Edition的簡稱。它是Sun Microsystems公司在Java的品脾之下的四種平臺之一,其他三種分別是J2SE, J2EE和Java Card。J2ME的目標是消費類設備和嵌入式設備市場,包括各種電子產品,比如手機、PDA、傳呼機、機頂盒等等。J2ME的開發進程同樣由JCP(Java Community Process)來負責。
J2ME繼承了Java優秀的跨平臺兼容性,這是它與其他無線開發技術相比的優勢之一。它爲創建小型設備上的各種應用程序提供了完整的解決方案。
1.2. J2ME總體架構介紹
J2ME架構如下所示:
各種Profile(MIDP,Foundation profile,KJava等)
各種Configuration(CLDC/CDC)
各種Java虛擬機(KVM/CVM)
主機操作系統
其中各種Java虛擬機,Configuration以及Profile構成了J2ME程序完整的運行時環境。
由Configuration決定了相應的Java虛擬機。比如CDC Configuration決定了CVM。而Profile則是一組位於Configuration之上的API,爲開發特定領域的應用提供支持。
此外,還有一些開發和部署各種應用的工具。
1.2.1. Configuration介紹
劃分Configuration的主要依據是目標設備的處理器能力和內存容量,而與其網絡連接的類型和速度無關。這樣做的理由之一就是,即便各種小型設備在功能和形式等方面大相徑庭,但是它們通常使用相似的處理器和數量接近的內存,所以以此爲依據,對它們進行橫向的分組是比較合理的。
目前J2ME的兩種標準Configuration是:
l CDC(Connected Device Configuration)
l CLDC(Connected Limited Device Configuration)
1.2.1.1. CDC
CDC的目標設備爲間歇性的連接到網絡的設備,比如機頂盒,汽車導航系統等等。相對來說,它要比CLDC的覆蓋範圍更廣一些,其目標的處理能力也更強大一些。CDC包含功能完整的Java虛擬機,與J2SE當前使用的虛擬機類似。
以下列出了部分官方J2ME規範定義的CDC設備資源需求:(請以JCP網站上最新的相應規範爲準)
l 具有32位處理器
l 具有2M以上內存供Java使用
l 連接到網絡,通常是無線間歇連接,而且具有有限的帶寬。
l 用戶界面不是必須
l 其他的要求…….
1.2.1.2. CLDC
CLDC Configuration的應用更爲廣泛一些,它的目標設備主要包括手機,PDA,掌上電腦等等。其處理能力比CDC設備要相應的弱一些。
以下列出了部分官方J2ME規範定義的CLDC設備資源需求:(請以JCP網站上最新的相應規範爲準)
l 具有160K到512K以上內存供Java使用
l 具有有限的電源(通常是用電池來供電)
l 連接到網絡,通常是無線間歇連接,而且具有有限的帶寬。
l 用戶界面不是必須
l 其他的要求…….
需要注意的是,區分這兩種Configuration的主要依據應該放在處理能力,內存量,是否使用電池等。而不是其網絡連接的類型和速度。而且這兩種規範之間的界限也越來越模糊了。
1.2.2. 虛擬機介紹
如前所述,Configuration定義的功能決定了相應的虛擬機。所以目前有兩種虛擬機:
l KVM(Kilo Virtual Machine),對應於CLDC
l CVM,對應於CDC
1.2.2.1. KVM
KVM專門爲資源受限的小型設備所設計。它來源於Sun研究院的“Spotless”工程。KVM是符合JVM規範的虛擬機,除了在爲滿足某些特殊的需求而背離JVM規範之外。
1.2.2.2. CVM
CVM用於處理能力較強的消費類和嵌入式設備,它支持Java 1.3虛擬機的全部功能。
1.2.3. Profile介紹
Profile定義了應用程序所支持的設備類型,爲特定域的應用開發提供支持。J2ME目前已經包括了多種Profile,比如MIDP,PDA Profile,KJava, Foundation Profile等等。以下只介紹MIDP。
1.2.3.1. MIDP
MIDP即Mobile Information Device Profile,它提供了移動設備使用的API,比如手機。它定義了用戶界面,網絡以及持久存儲等相關的類。運行於MIDP下的應用稱爲MIDlet。後續的示例程序就是一個MIDlet。MIDP允許把新的應用程序下載到用戶設備上,比如下載一個小遊戲到手機上面並運行。
1.3. 搭建簡單的開發環境
本文只介紹基於Sun提供的J2ME無線開發工具包的開發活動。不包括與各種IDE的配合使
用比如JbuilderX等等。也不包括其他廠商提供的開發包的介紹,比如Nokia S40系列的開發包。您有興趣的話,可以參考其他資料自行學習。
1.3.1. 下載JDK和J2ME無線開發工具包(WTK)
這些都可以到Sun的官方網站免費得到,安裝也很方便。本文基於JDK1.4.2和WTK1.0.4。您可以下載更高版本的開發工具。
本文的安裝路徑爲:
C:/jdk142以及C:/wtk104,您可以根據自己的情況合理更改。
1.3.2. 設置環境變量
在Windows 2000和XP上面,通常可以這樣設置:右擊我的電腦—>屬性—>高級—>環境變量—>系統變量,然後添加JDK和WTK的路徑即可,也就是將C:/jdk142/bin以及C:/wtk104/bin添加到PATH變量的後面即可。
驗證以下是否設定正確,可以在命令行輸入WTK包含的preverify命令。如果系統提示找不到命令,則說明沒有設定好,反之則已經設定好了。
此外,設置如下的環境變量,可以方便在命令行上編譯和運行J2ME程序。
變量J2MEWTK_HOME 設定爲:C:/wtk104
變量MIDPAPI 設定爲: %J2MEWTK_HOME%/lib/midpapi.zip
變量J2MECLASSPATH 設定爲:
%J2MEWTK_HOME%/wtklib/kenv.zip;%J2MEWTK_HOME%/wtklib/kevm.jar;%J2MEWTK_HOME%/wtklib/lime.jar
在Windows 2000和XP上可以參考上訴方法,添加相應的變量即可。
1.4. 一個簡單的Midlet示例
從偉大的“K&R”開始,“Hello World”幾乎成了入門必修課。呵呵,我們也順其自然吧。本文先列出代碼,並適當的講解以下,然後講述如何編譯和運行它,然後講述一些其他的知識。
代碼如下:
//HelloWorld.java
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class HelloWorld extends MIDlet {
//MIDlet 的顯示
private Display display;
//用於顯示"Hello World"字樣
private TextBox box = null;
//Constructor
public HelloWorld()
{
box = new TextBox("Hello World", "Hello World", 20, 0);
}
//MIDlet應用程序生命週期管理方法之一,負責激活MIDlet
public void startApp()
{
display = Display.getDisplay(this);
display.setCurrent(box);
}
//MIDlet應用程序生命週期管理方法之一,負責暫停MIDlet,本例無需如此
public void pauseApp()
{
}
//MIDlet應用程序生命週期管理方法之一,負責釋放資源
public void destroyApp(boolean unconditional)
{
box = null;
}
}
下面對代碼進行分析。
該類繼承了javax.microedition.midlet.MIDlet類。該類是J2ME中所有MIDlet的父類。
Display類來自javax.microedition.lcdui.Display。代表了MIDP設備的顯示器。可以通過Display類的靜態方法getDisplay()獲得顯示器,並通過靜態方法setCurrent()使得HelloWorld MIDlet可以在設備上顯示“Hello World”字樣。
TextBox是字符串“Hello World”的載體,它在構造函數中被實例化。
startApp(),pauseApp()和destroyApp(boolean unconditional)是應用程序管理系統(Application Management System)用來管理MIDlet的執行的,稱它們爲應用程序生命週期管理方法。開發過Applet的讀者,可以與Applet的start(),stop()和destroy()相類比。應用程序的有三種可能的狀態:運行狀態,暫停狀態和銷燬狀態。這些狀態和方法之間的轉換關係如下:
l public void startApp() :MIDlet從暫停向運行狀態轉變時,需要調用這個方法,通常會初始化運行MIDlet的所需的所有對象,並設置當前的顯示器。需要注意的是,該方法可以多次被調用,所以對於那些僅需一次初始化的程序,不要放入這個方法裏,而是放到MIDlet的構造函數裏。
l public void pauseApp() :MIDlet從運行轉向暫停時,需要調用這個方法。一般會執行暫停當前運行的所有線程等活動。
l public void destroyApp(boolean unconditional) :當應用程序不再需要,而要進入銷燬狀態時,需要調用這個方法。它將釋放應用程序的全部資源。既可以從暫停狀態轉到銷燬狀態,也可以從運行狀態轉到銷燬狀態。
1.4.1. 編譯
爲了方便起見,將本程序源文件置於C:/. 。先在這個目錄下建立一個tmpclassess目錄,以備後用。
使用命令行,輸入以下命令編譯程序:
javac -d tmpclasses -bootclasspath %MIDPAPI% -classpath %J2MECLASSPATH% HelloWorld.java
該命令編譯上訴程序,並在tmpclasses目錄下創建HelloWorld.class文件。-bootclasspath 和-classpath的作用是設置正確的啓動路徑和類路徑,從而只使用J2ME的類。
1.4.2. 預驗證
在J2SE環境下,只需類文件即可運行Java程序,但是在J2ME環境下,還需要有預驗證這一
因爲出於安全的考慮,任何進入運行時的class文件,都要經過Byte Code驗證器(Byte Code Verifier)的驗證,以保證程序代碼安全有效。比如:不會溢出堆棧,不包含惡意代碼,經過了合理的初始化等等。只有通過了審覈的代碼,纔會被JVM執行。這對於普通應用程序的執行環境來說,是可以接受的硬件要求。但是對於像CLDC這樣的設備來說,它們的資源太受限了。如果期望在運行時執行同J2SE VM一樣的驗證程序,是不現實的。因此,我們需要把大部分的驗證工作交給開發MIDlet程序的機器來完成,而MIDlet的目標設備只需執行很少的驗證工作即可。這就導致了預驗證步驟的出現。
在預驗證的過程中,會在class文件中加入一些特殊的符號,用於簡化目標設備的驗證工作。
預驗證之前,可以創建一個classes目錄,用於保存驗證通過的class文件。具體的命令如下:
preverify -classpath %MIDPAPI%;tmpclass -d classes tmpclasses
1.4.3. 創建jar文件
首先進入classes目錄,然後執行:
jar cvf HelloWorld.jar HelloWorld.class
這會把程序包含的所有類和資源壓縮到JAR文件,併爲其創建打包清單。
1.4.4. 創建jad文件
JAD(Java Application Descriptor)文件,用於描述該JAR文件包括的程序的一些屬性,比如
大小等等。在實際部署時,該文件會先被下載到目標設備上,由目標設備的應用程序管理系統(Application Management System)來處理並決定是否下載真正的JAR文件。
本例的JAD文件如下,HelloWorld.jad:
MIDlet-1: Hello,,HelloWorld
MIDlet-Name: HelloWorld
MIDlet-Version: 1.0
MIDlet-Verdor: ORA
MIDlet-Jar-URL: HelloWorld.jar
MIDlet-Jar-Size: 860
這個文件內容很清晰,包括名稱,版本,JAR文件地址和大小等信息。關於JAD文件的具體語法,本文不作具體的介紹,您可以參考相關資源。
1.4.5. 在仿真器中運行
首先,需要把JAD和JAR文件置於同一個目錄下,比如classes。
然後運行如下命令即可:
emulator -Xdescriptor:HelloWorld.jad
1.5. 開發技巧,性能注意事項
使用局部變量。使用局部變量會比使用類成員要快。
使用StringBuffer而不是字符串串聯。字符串串聯會引起大量對象的創建和回收,降低了性能。
使用盡量少的方法調用。由於JVM使用堆棧來加載和存儲方法調用,所以應儘量少用方法調用,降低開銷。
儘量重用對象。對象的創建和回收都會帶來開銷,所以應該精心設計,儘量重用現有的對象。比如在方法內傳遞對象的引用,然後修改對象的值。
使用線程,避免同步。對於運行時間較長的操作,需要一個獨立的線程來執行,避免同步可提高性能。
對PNG圖片進行優化處理。
使用“混淆器”。除了可以防止class文件被反編譯之外,也可以在一定程度上減少class文件的尺寸。
1.6. 總結
正如本文的摘要所述,這是一篇入門的文章。爲此,文章捨棄了許多內容。筆者認爲那些內容更適合出現在其他主題的文章中。呵呵,希望這篇文章能給您帶來一些收穫,幫助您順利的搭上J2ME開發的快車。
歡迎指正,歡迎討論!
歡迎轉載,請註明出處!保留相關權力。