在本章之前所介紹的都是怎麼樣編寫J2ME的源文件(即*.Java文件)。因為J2ME不同於J2SE程序的開發流程,在編寫好Java源文件後,我們還要繼續進行如下工作:
l 編譯
l 混淆(可選)
l 預審核
l 打包
打包後,將獲得了一個jar文件。接下來為jar文件編寫一個以jad為後綴的描述文件。最後通過各種途徑將jar文件、jad描述文件傳輸到移動設備上運行即可。
完整的MIDP手機程序開發流程如下表(其中混淆為可選):
流程
工具
輸入
輸出
編譯
Javac.exe編譯
源文件(*.Java)
未混淆的類文件(*.class)
混淆
第三方提供的工具
未混淆的類文件(*.class)
混淆後的類文件(*.class)
預審
preverify.exe預審核
混淆後的類文件(*.class)
經過預先審核的類文件(*.class)
包
jar.exe打包
經過預先審核的類文件(*.class)
包文件(*.jar)
編寫描述文件
文本編輯工具
描述文件(*.jad)
安裝運行
傳輸工具
(IR/BT/數據線/OTA)
包文件(*.jar)和
描述文件(*.jad)
在仿真器或手機上正式運行
下面將會介紹每個步驟。當利用集成開發環境(諸如JBuilder、NetBeans、Sun ONE Studio、Eclipse等)時,這些工具不僅可以很快的幫我們建立起代碼的主干,而且可以幫助我們自動的完成上面的大部份工作(關於集成開發環境的利用見後面的章節)。在利用IDE開發之前,開發者有必要了解其中每一步的原理。
編譯
編譯就是將我們所編制的*.Java 文文件,編譯成為二進制的*.class文件(計算機只認識二進制!)。Javac.exe是由Sun公司編寫的一個編譯器,它可以把*.Java文件編譯成為*.class文件。注意:如果一個*.Java文件中定義了三個類,它就將被編譯成三個*.class文件。
混淆(可選)
由於class文件格式透明的緣故,Java文件很容易被反匯編。因此,如果你不希望別人掌握你的源代碼的話,你一定要進行混淆(obfuscate)。所謂混淆,就是利用工具,將方法名、類名改成沒有實際意義的特定的字符及代號,增加閱讀的難度。這樣就充分的保護了我們自己的知識產權。而且混淆還有個意想不到的好處,就是減少程序的大小。這是由於混淆器將我們設定的方法名、類名變成沒有意義的短字符或代碼,無形中減少了程序的大小。對於手機程序設計來講尤為重要,每K的減少都意味著可以獲得更多的空間。混淆器都是第三方軟件開發商提供的,許多都是開源的,可以免費使用。常見的混淆器見下表:
名稱
地址
特點
JODE
http://jode.sourceforge.Net/
開源
ProGuard
http://proguard.sourceforge.Net/
開源
RetroGuard
http://www.retrologic.com/
開源,中國移動百寶箱強制使用
DashO
http://www.preemptive.com/
商業軟件,一般專業公司使用,昂貴
ZKM
http://www.zelix.com/
商業軟件可試用
JBuilder
http://www.borland.com/
集成開發環境中內附混淆功能,但JBuilder的價格也不便宜。
預審核
在完成編譯後,我們必須要對*.class文件進行預審核,這和傳統的Java程序(Applet、Servlet)是不同的。因為class在傳輸過程中容易損壞或是被篡改,傳統的Java程序在運行前,都在本地機器上對.class進行Byte Code的審核。而對於手機這樣的資源有限設備而言,在手機上進行大量的此類的審核是極為浪費資源(如占用CPU的時間、消耗電力等)。因此,我們必須先在PC機上使用preverify.exe進行一部份預選審核工作。這樣,在手機上進行的審核工作就大量減少了。
打包與編寫描述文件
MIDP可執行文件後綴名為jar。利用jar file.class就能將通過預審核的*.class文件,打包成 MIDP認可的可執行文件。後綴名為jad的文件是jar文件的描述文件,jad文件詳細介紹見第二節。
在仿真器或手機上安裝運行
有了jar及jad文文件後,我們就可以把它們放到仿真器或手機上運行了。至於如何把它們放到手機上,根據手機的功能不同,有如下方法可以選擇:
l 使用數據線,將PC與手機相連,下載文件
l 使用紅外線
l 使用藍牙
l 使用OTA空中下載(利用短信/WAP)
JAM (Java Application Manager) 中文一般翻譯為應用程序管理器。在有些文檔中,JAM也被叫做AMS (application manager software),這兩個術語所描述的概念是完全一樣的。簡單來講,JAM是管理移動設備上所有J2ME應用程序的軟件,負責J2ME應用程序的下載、安裝、更新與刪除。JAM由是移動設備本身所提供的,不同公司的實現略有不同,初級開發人員只要知道其作用就可以了。
對MIDlet Suite簡單理解是MIDlet程序的一個集合。MIDlet Suite包含了一個或多個MIDlet、資源文件以及JAR manifest,這些內容被打包成一個JAR包。通常情況上講MIDlet Suite還需要一個外部的JAD描述文件。
MIDlet Suite是為了解決多個MIDlet受控訪問、共享資源的問題而提出的模型。舉個共享資源的例子:在前面的章節中我們已經介紹過,RMS的共享在一般情況下是以MIDlet Suite為單位進行的,即同一個MIDlet Suite中的MIDlet可以安全的共享所在MIDlet Suite中的RMS。因此,當多個MIDlet要共享RMS時,就可以將它們放進一個MIDlet Suite中。為了保證安全性,MIDlet Suite中的MIDlet、資源文件都不能獨立安裝、刪除或更新。即MIDlet Suite必須作為一個整體包來對其操作。對於設備來講MIDlet Suite是一個基本單位。
前面我們介紹過,JAR文件就是經打包後的可執行文件,包括下面各種元素:
1) 實現MIDlet的類文件;
2) MIDlet中用到的任何資源文件(包括圖像、聲音文件等);
3) 關於JAR內容的一份JAR manifest描述。
根據MIDP規范的規定,每個MIDlet Suite的JAR文件中必須包含一個名為mainifest.mf的文件,這個文件用於描述MIDlet Suite的各種屬性。
其中,必須包含以下屬性:
屬性名
說明
MIDlet-Name
MIDlet Suite的名稱
MIDlet-Version
MIDlet Suite的版本號,格式為主版本.次版本.微版本,例如0.0.0,這也是版本號的默認值。版本號主要用於安裝或升級。
MIDlet-Vendor
MIDlet Suite的提供商
如果JAD描述文件中未提供下列屬性,則JAR manifest必須提供的屬性:
屬性名
說明
MIDlet-<n>
用來描述MIDlet Suite中所包含MIDlet的信息。第一個MIDlet就以MIDlet-1代表,第二個MIDlet就以MIDlet-2代表。(最小從1開始,不能重復,不能間隔)。屬性值格式如下:
應用程序名稱,圖標,類名稱(以逗號間隔)
其中應用程序名稱由開發人員指定;圖標必須是位於JAR中的PNG格式圖像文件(可選);類名稱為MIDlet的類文件名。
MicroEdition-Profile
MIDlet Suite所需要profile的名稱及版本號,如MIDP-1.0。多個profile用空格來分隔。如果所指定的任何一個profile設備無法提供(包括版本不兼容),JAM將拒絕安裝該MIDlet Suite。
MicroEdition-Configuration
MIDlet Suite所需要configuration名稱及版本號,如CLDC-1.1。如果設備無法提供該configuration,那麼JAM將拒絕安裝該configuration。
可選以下屬性:
屬性名
說明
MIDlet-Description
關於此MIDlet Suite的簡短說明。
MIDlet-Icon
MIDlet Suite的圖標的文件名。必須位於JAR文件中,以PNG為格式。
MIDlet-Info-URL
關於MIDlet Suite更詳細描述的URL地址。
MIDlet-Data-Size
MIDlet Suite所需要的持久化數據儲存(persistent data,即RMS)的大小,默認值為0。
MIDlet-Permissions
執行此MIDlet Suite的主要權限(見上章)
MIDlet-Permissions-Opt
執行此MIDlet Suite的可選權限(見上章)
MIDlet-Push-<n>
與Javax.microedition.io.PushRegistry有關,詳見Push章。
MIDlet-Install-Notify
向此URL發送一個POST請求,報告此MIDlet Suite的安裝狀況,比如是全新安裝還是升級安裝。
MIDlet-Delete-Notify
向此URL發送一個POST請求,報告此MIDlet Suite的刪除狀況。
MIDlet-Delete-Confirm
當用戶選擇刪除MIDlet Suite時,將給予用戶的提示信息。
應用程序專用的任何屬性
不以“MIDlet-”或“MicroEdition-”開頭
注意:所有屬性都可以通過調用MIDlet.getAppProperty方法取得。
范例:我們假設一個名字為MyGame的MIDlet Suite,由PPJ2ME公司提供,版本為1.1.1。其中包括兩個MIDlet:MyGame01,MyGame02。那麼對應mainifest.mf文件可能是這樣的:
mainifest.mf
MIDlet-Name: MyGame
MIDlet-Version: 1.1.1
MIDlet-Vendor: PPJ2ME
MIDlet-1: MyGame01, /MyGame01.png, com.PPJ2ME.MyGame01
MIDlet-2: MyGame02, /MyGame02.png, com.PPJ2ME.MyGame02
MicroEdition-Profile: MIDP-2.0
MicroEdition-Configuration: CLDC-1.1
下面談談JAD描述文件,雖然某些設備上,JAM並不一定要求有JAD描述文件。尤其在MIDP1.0時,JAD描述文件似乎用處不大。但在MIDP2.0中,JAD描述文件涉及了許多安全方面問題,顯得尤為重要。一般而言,在下載JAR文件前,會先下載JAD描述文件,以讓設備了解該MIDlet Suite是否適合自己。避免直接下載JAR文件導致大量的成本消耗。這也是設計JAD描述文件的初衷之一。另一個目的就是提供在不更改JAR的前提下修改某些屬性值的能力。
JAD描述文件為純文本文件,文件擴展名為.jad。JAD描述文件和JAR manifest有很多相似的地方,所以部分說明請參見上一節。
如果有JAD描述文件,則JAD描述文件必須提供如下屬性:
屬性名
說明
MIDlet-Name
略
MIDlet-Version
略
MIDlet-Vendor
略
MIDlet-Jar-URL
下載該MIDlet Suite的URL地址。雖然這裡可以使用絕對位置或相對位置,但還是建議用絕對位置。
MIDlet-Jar-Size
JAR文件的大小,計算單位為字節。
如果JAR manifest未提供下列屬性,JAD描述文件中則必須提供:
屬性名
說明
MIDlet-<n>
略
MicroEdition-Profile
略
MicroEdition-Configuration
略
可選以下屬性:
屬性名
說明
MIDlet-Description
略
MIDlet-Icon
略
MIDlet-Info-URL
略
MIDlet-Data-Size
略
MIDlet-Permissions
略
MIDlet-Permissions-Opt
略
MIDlet-Push-<n>
略
MIDlet-Install-Notify
略
MIDlet-Delete-Notify
略
MIDlet-Delete-Confirm
略
應用程序專用的任何屬性
略
對應用程序自己的屬性的說明
應用程序可以利用jad來記錄自己的專用屬性,只要不以“MIDlet-”或“MicroEdition-”開頭。這往往非常流行。因為一旦打包成jar,就不方便對其進行修改。而jad是文本文件,方便修改。因此這些屬性常用來記錄和設備相關的信息或者是網絡地址等。這在移植程序時,減輕了很大的工作量。所有屬性都可以通過調用MIDlet.getAppProperty方法取得。
范例:我們假設一個名字為MyGame的MIDlet Suite,由PPJ2ME公司提供,版本為1.1.1。其中包括兩個MIDlet:MyGame01,MyGame02。那麼其對應的JAD描述文件可能是這樣的:
MyGame.jad
MIDlet-Name: MyGame
MIDlet-Version: 1.1.1
MIDlet-Vendor: PPJ2ME
MIDlet-1: MyGame01, /MyGame01.png, com.PPJ2ME.MyGame01
MIDlet-2: MyGame02, /MyGame02.png, com.PPJ2ME.MyGame02
MicroEdition-Profile: MIDP-2.0
MicroEdition-Configuration: CLDC-1.1
MIDlet-Description: That our sample game.
MIDlet-Jar-URL: http://www.ppJ2ME.com/game/MyGame.jar
MIDlet-Jar-Size: 7378
MIDlet-Data-Size: 256
前面介紹JAD描述文件的時候已經介紹了:為什麼有了JAR manifest的同時還要有JAD描述文件存在的原因。那麼這兩者之間還有什麼必然的聯系嗎?
細心的讀者可能已經發現,JAD描述文件和JAR manifest中都包括了三個相同的必備屬性:
屬性名
l MIDlet-Name
l MIDlet-Version
l MIDlet-Vendor
出於安全性考慮,MIDP規范規定,如果JAD描述文件及JAR manifest中這三個必備屬性有任何不同的話,JAM是不會安裝該MIDlet Suite的。
在調用MIDlet.getAppProperty的時候:對於不可信任的MIDlet Suite,JAD描述文件的屬性會覆蓋JAR manifest中的屬性。對於可信任的MIDlet Suite,兩者必須相同。(有關於可信任及不可信任MIDlet Suite的概念,在上章中有詳細說明)。
雖然現在MIDP設備大部分都預裝了幾個MIDP Suite,但對於用戶而言,總是希望得到最新的、最實用的MIDP Suite。這就要求MIDP設備提供下載機制。以前最可行的方法就是利用與電腦的串行電纜聯接,從電腦上下載MIDP Suite。但現在最流行的方式就是OTA方式。用戶可以在任何無線網絡覆蓋的地方下載自己喜歡的MIDP Suite,這些MIDP Suite存放在支持OTA方式的許多服務器上。
MIDP2.0中規定,OTA下載的規范是HTTP協議的。例如MIDP設備上的WWW、WAP或i-Mode都是基於HTTP協議的。因為像WAP這種協議可能不是基於IP的,在MIDP設備與服務器中間需要中轉站等轉接設備,為了方便我們進一步講解,我們將忽略這些中轉站的存在,而把OTA看作是MIDP設備與服務器之間的直接聯系。
一個典型的OTA安裝請求,包括如下步驟:
1)用戶在下載MIDP Suite時,首先要給MIDP設備一個URL地址,以確定使用哪台服務器及服務器的哪個MIDlet文件。第(1)項和第(2)項可能不是必須執行的,如果用戶指定的URL是一個JAR文件,則直接進行第(3)項。如果URL指定的是一個JAD描述文件,則MIDP設備向服務器發出下載JAD描述文件的請求。
2)服務將返回所請求的JAD描述文件。在成功收到JAD描述文件後,MIDP設備將檢驗JAD描述的安全及規格,檢查設備是否能正確運行該MIDP Suite。這種做法保證了在試圖傳輸較大的JAR文件前,先確定設備擁有運行MIDP Suite所需要的適當能力及資源。
3)如果用戶所指定的URL指向了一個JAR文件,或第(2)項檢查成功,則MIDP設備將向服務發出下載JAR文件的請求。
4)服務器將返回所請求的JAR文件。下載成功後,MIDP Suite將被安裝。
5)在可能的情況下,MIDP設備向服務發送一條安裝狀態的通知,通知該MIDP Suite是否安裝成功。即使在MIDP設備無法向服務器發出通知的情況下,該MIDP Suite仍然可以正常運行。
當某個MIDP Suite產生更高的版本時,用戶往往會嘗試更新。更新是不會被自動運行的,需要用戶再重復一遍上節所介紹的安裝步驟,值得注意的是:不管第二次下載的版本號是否與設備上已有MIDP Suite版本號相同,甚至是比原有版本更低,設備都會為將其視為MIDP Suite的升級。但不論什麼情況,JAM都會通知用戶要安裝的MIDP Suite是比現有的高、相同或低,然後經用戶確認後繼續。具體還要參考JAM的實現。
在更新的過程中,原有MIDP Suite的RMS存儲記錄是否被更新後的MIDP Suite所用,按照如下規則進行:
1) 如果新MIDP Suite的加密簽名(詳見安全章節)與原來的相同,則RMS存儲記錄將被保留給新MIDP Suite所用。
2) 如果新MIDP Suite的JAR文件manifest中URL、主機和路徑與原有的相同,則RMS存儲記錄將被保留給新MIDP Suite所用。
3) 如果新MIDP Suite的JAD文件中URL、主機和路徑與原有的相同,則RMS存儲記錄將被保留給新MIDP Suite所用。
4) 如果上述條件沒有一條滿足,則JAM將向用戶詢問,RMS是否為新MIDP Suite所用。
如果用戶從設備上刪除MIDP Suite,用戶一般情況下會被JAM詢問是否確定刪除。在此同時,如果JAR中manifest或JAD文件中包含了MIDlet-Delete-Confirm屬性,則該屬性所定義的內容,也將同時被包括進刪除的提示信息內。因此,在該屬性內,應同時向用戶提示諸如MIDP Suite中所有MIDlet及RMS都將被刪除的信息。
在MIDlet Suite安裝和刪除時,MIDlet Suite會嘗試向當初下載該MIDlet Suite的服務器進行報告。這就會用到JAR中manifest或JAD描述文件的MIDlet-Install-Notify和MIDlet-Delete-Notify屬性。由於這兩個屬性是可選的,因此,MIDlet Suite正確向服務器發送狀況也不是必須的。也就是說,不論安裝或刪除狀況是否正確向服務器報送,該MIDlet Suite的安裝及刪除也會順利進行。
安裝:在MIDlet Suite安裝時,該狀態報告發往MIDlet-Install-Notify中所指定的URL(注意:不論是安裝不刪除狀況的發送,其發送的都是POST請求,該請求的第一行將包括一個有效的代碼,詳見下表)。如果狀況報告無法正確向服務器報告,在該設備的網絡連通時,MIDlet Suite將再次向服務器報告。
刪除:在MIDlet Suite刪除時,該狀態報告發往MIDlet-Delete-Notify中所指定的URL。刪除狀況不會被立即報告,而是在下次發送安裝狀況時向服務器報告。如果狀況報告無法正確向服務器報告,在該設備的網絡連通時,MIDlet Suite將再次向服務器報告。
POST代碼
代表消息
900
成功
901
內存不足
902
用戶取消
903
服務丟失
904
JAR大小不匹配
905
屬性不匹配
906
無效的JAD
907
無效的JAR
908
不兼容的configuration或profile
909
驗證失敗
910
授權失敗
911
Push注冊失敗
912
刪除通知