程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> J2ME >> 深入了解MIDP——基礎篇

深入了解MIDP——基礎篇

編輯:J2ME

本文主要介紹MIDP的基本概念。因為注意到國內的Java站點介紹J2ME的還比較少,所以就寫了本文。如果有什麼不妥的地方,歡迎您email我,討論商榷。
如您要轉貼,請保留原出處,並勿做刪改。謝謝。
本文是“J2ME的基本介紹”系列文章的後續,在基礎篇中,將主要介紹MIDP的組織結構,和MIDlet的LifeCycle,並通過一個實例,編寫一個MIDlet程序。本文的內容如下:
1、MIDP中的類
2、MIDlet的LifeCycle
3、a MIDlet program
4、JAR 與.Jad
5、put it together.
-----------------
0。MID(Mobile Information Device )的特性。
  由於MID這類設備,在屏幕、內存、處理器等問題上有諸多限制,在手機或是
PDA等MID上開發應用程序必須要考慮一些技術上的特殊點。
下面給出一些設備的特性:
  顯示(display):96x54 (最小屏幕尺寸),1bit(最小色深,單色)
  輸入設備: “one-handed keyboard”(指ITU-T手機鍵盤)
  “two-handedkeyboard” (指標准鍵盤,即QWERTY鍵盤)觸摸屏。
  內存:128kb-MIDP組件。
         8kb-應用程序生成的Persistent data(關於Persistent data,我會在將來講RMS時,詳細說明,這裡有個概念就行了) 32kb-Java runtime環境。
  網絡: 雙向的,無線的,間斷的,帶寬有限的網絡
  內核(kernel):至少要能運行KVM
  還有很多軟件上的特性,如讀寫non-volatile內存(就是掉電後不會失去內容 的內存,如Flash)。讀寫無線設備接口的API,等等。
  除了上訴技術上的問題,你還得注意你的程序要簡單易用且穩定可靠。尤其是可靠性,你開發的是通訊設備,用戶是不能忍受程序有什麼纰漏而影響到通話的。你要牢記這一點。

1。MIDP的類庫
  如前文所述,sun在CLDC之上定義了MIDP(Mobile Information Device Pro-file)層,用以提供對UI、永久存儲介質(persistinace storage)、和網絡等更高層的(相對於CLDC)支持。那麼,讓我們來具體看看MIDP的類庫。
MIDP由四個Javax.microedition包組成,它們包括:
javax.microedition.rms-----關於永久存儲介質(注:rms是Record Management System的縮寫)Javax.microedition.midlet--定義了MIDlet的框架,以及MIDlet與環境的交互。
Javax.microedition.io------網絡支持
Javax.microedition.lcdui---UI(User Interface)(注:UI分為high-level和low-level兩種API。)                     
注:如果在加上語言和實用類(java.lang和Java.util)則有六個。

2。MIDPlet
  MIDP中定義的應用程序稱為MIDlet。任何一個MIDlet都是javax.microedition.midlet.MIDlet的子類,必須繼承自javax.microedition.midlet.MIDlet。這很顯而易見。我們在J2SE中編過Applet,Applet就必須繼承自Java.applet.Applet。是不是很類似。請看下圖,說明了MIDlet的繼承體系。

┌────────────────┐
│Javax.microedition.midlet.MIDlet│
└────────────────┘
             ↓
    ┌──────┐
    │MyMIDlet│
    └──────┘

圖1 MIDlet的繼承體系
本文是“J2ME的基本介紹”系列文章的後續,在基礎篇中,將主要介紹MIDP的組織結構,和MIDlet的LifeCycle,並通過一個實例,編寫一個MIDlet程序。

3。編譯一個簡單的MIDlet,並執行。
下面我先給出一個簡單的HelloWorld程序,然後進行分析。
===============================源程序==================================
//HelloWorld.Java,一個最簡單的MIDlet程序。
import Javax.microedition.midlet.*;
import Javax.microedition.lcdui.*;
public class HelloWorld extends MIDlet implements CommandListener {
private Command exitCommand;
private TextBox tb;
public HelloWorld(){
exitCommand =new Command("Exit",Command.EXIT,1);
tb =new TextBox("Hello MIDlet","Hello,World!",15,0);
tb.addCommand(exitCommand);
tb.setCommandListener(this);
}
protected void startApp(){
Display.getDisplay(this).setCurrent(tb);
}
protected void pauseApp(){
}
protected void destroyApp(boolean u){
}
public void commandAction(Command c,Displayable d){
if (c ==exitCommand){
destroyApp(false);
notifyDestroyed();
}
}
}
===============================源程序完================================
  該程序顯示“HelloWorld”字符串。程序本身非常簡單,如果你熟悉JavaApplet編程的話,你會發現與Applet很類似。好,我們先把它編譯,運行一下看看。
編譯之前的准備:
硬件:因為是Java,所以內存最少有128MB以上,CPU最好是PII或更高。
平台:最好是win2000,win98的中文顯示會有問題,解決起來比較麻煩。Linux我沒有試過,英文我想應該都沒什麼問題,但中文顯示我估計可能會有些麻煩,如果有試過的朋友,請一定告訴我。
SDK:你需要有(下述軟件都可在sun網站上免費下載)
1。Java 2 SDK 1.3或以上。
2。J2ME Wireless Toolkit 1.0.3  
    以下可選:
    sun的IDE:Forte for Java。(如果你上的是寬帶,或不是自己付網費的話 ^-^)
  下載好後,先安裝JDK1.3,(具體關於安裝和設置我就不詳述了,想來大家都很清楚。如果您不清楚,請參考相應資料。)在安裝J2ME Wireless Toolkit 1.0.3,它會自動找到您的JDK1.3,並作相應設置。如果您不用命令行的話,環境變量也不用設置直接可在圖形界面上運行,非常方便。關於環境變量的設置請自己參考手冊。
  
編譯的步驟:
如果你按上述已經安裝好JDK和J2mewtk,請按以下步驟編譯,實際上是非常簡單的:(注:下述默任JDK安裝在c:\JDK1.3,J2ME Wirless Toolkit 安裝在c:\J2MEwtk\)
1. 開始->程序->J2ME Wirless ToolKit 1.0.3->KToolBar
2. 這時會出現"J2ME Wirless ToolKit"窗口,點"New project"按鍵,在Project name項填:HelloWorld;在MIDLet Class Name填:HelloWorld。點擊Creat project。
3. 這時會出現Setting for project對話窗,采取默認即可。點擊ok。
4. 這時請注意,因為沒有down sun的IDE,所以你要手工把你事先編輯好的Hello World.Java放置在c:\J2MEwtk\aPPS\HelloWorld\src\目錄下。這時,按“Build”鍵,如果一切正常,將提示編譯完畢。這時在device下拉選單中選定你想要的設備,再按“run”鍵,終於大功告成。你可以多選幾個不同設備,感受一下,不錯吧。

4.MIDlet的Lifecycle
  在上一節裡,我們已經成功編譯並運行了一個簡單的MIDlet程序。現在,讓我們來分析一下MIDlet的結構,和其Lifecycle。
  通過對源程序的觀察,我們可以發現MIDlet程序的運行是由startApp(),pauseApp()和destroyApp()這3個方法控制的。它們在Javax.microedition.midlet.MIDlet中定義。所有的MIDlet都必須有這3個方法。顧名思義startApp()方法用於標志一個MIDlet的開始執行。不過這裡要注意一點,與HelloWorld程序的constrctor不同。startApp()不光是在初始化完一個MIDlet時執行,只要該MIDLet被從Paused態激活(變為Active態),startApp()就會被調用。pauseApp()方法標志著MIDlet進入Pause態。而destroyApp()方法標志著MIDlet進入destroyed態。(注意:這裡嚴格的講應該說成:方法被調用並成功返回標志著...)
  看完上面的描述,大家可能會滿頭霧水,又是方法,又是狀態的,什麼跟什麼嗎?這還得從MIDlet的執行機制講起。MIDlet的執行是通過Application Management software來管理的。這玩意兒是處在操作系統級別上來管理MIDlet運行的底層機制的總稱,所謂MIDlet state(MIDlet狀態)就是它一手操辦,控制管理的。MIDlet state確保了AMS隨時可以消滅該MIDlet,同時MIDlet也有辦法進入一個Pause態,並可再次激活。MIDlet State 分為Paused,Active,destroyed三種。當AMS創生一個新的MIDlet實體時,對應於MIDlet,表現為其constructor被調用,進入Paused狀態。當所有的准備工作都做好後,AMS判斷現在MIDlet可以運行了,於是調用MIDlet.startApp()方法。進入Active態。當AMS決定要把MIDlet轉入Paused態,就會調用MIDlet.pauseApp()方法,MIDlet就會暫停執行,通常Paused態會用於釋放所占資源。當AMS判斷MIDlet不再需要,就會調用MIDlet.destroyApp(),MIDlet被消滅。請注意我上述是站在AMS的角度在談AMS如何控制MIDlet的狀態改變。程序員也可請求MIDlet的狀態的變換,通過調用resumeRequest,notifyPaused,notifyDestroyed這三個方法。例如,我在上一節給出的例子中有如下程序片段:
...
public void commandAction(Command c,Displayable d){
  if (c ==exitCommand){
      destroyApp(false);
      notifyDestroyed();
}
...
這裡先把destroyApp()的unconditional值置為false,拋出一個MIDletStateChange
Exception 異常,表示MIDlet這時還不想被destroy。notityDestroyed()通知AMS
MIDlet進入destroyed態。具體的細節請參閱MIDP API文檔。
下面給出一個最簡單的MIDlet流程:
===========================FlowMIDlet.Java================================
import Javax.microedition.midlet.*;
public class FlowMIDlet extends MIDlet {
public void startApp() {
System.out.println( "In startApp..." );
pauseApp();
}
public void pauseApp() {
System.out.println( "In pauseApp..." );
destroyApp( true );
}
public void destroyApp( boolean unconditional) {
System.out.println( "In destroyApp..." );
}
}
===========================FlowMIDlet.Java完===============================
關於MIDlet狀態的改變可以用下圖表示:
                           destoryApp()
         +----------------------->--------------------------+
         |                                                  |
new() +========+  startApp()  +========+  destroyApp()  +===========+
----->| Paused |------------->| Active |--------------->| Destroyed |
     +========+              +========+                +===========+
         |      pauseApp()      |
         +---------<------------+
圖1 MIDlet的狀態轉變
  這裡還要說幾句閒話,關於AMS,其作用不止是控制MIDlet的運行狀態。它實際上際上負責了MIDlet的整個運行機制。關於AMS進一步的描述,請參見王森老師的文章-“利用Java撰寫手機應用-Java Application Manager篇”(《程序員》,12期,2001)。注意其中JAM就是AMS。
5.關於MIDlet Suites
  在上一節裡我主要從應用程序執行角度講述了MIDlet的lifecycle。但實際上MIDlet的lifeCycle是包括了從獲取(retrIEve),安裝,運行,卸載的一個整體。通過ASM來進行控制。其中運行這一步包括了我已經講過的三種狀態的改變。ASM為MIDlet的獲取,安裝,運行,卸載提供了一個運行環境。 如果你的MIDlet想要下載到實機上去運行,你就必須將其打包為一個jar文件。一個Jar文件中可能有多個MIDlet,我們把在同一Jar文件中的MIDlet的集合稱為MIDlet suite。一個打包好的MIDlet包括兩部分:一個.jad文檔,即描述文檔。和一個.jar文檔。其中.jad文檔是一個文本文檔,記錄MIDlet的屬性名稱和屬性值。.jar文件是一個壓縮包,其中有MIDlet的清單(Manifest.mf),編譯好的類(即MIDlet),圖片,文本等其他資源。
如下圖所示:
+==============================+
|MIDlet Suite(.Jar)            |
|                              |
| +----------+  +-----------+  |
| |MIDlet-1  |  |MIDlet-2   |  |     
| +----------+  +-----------+  |     +    描述文檔(.jad文檔)  
| +-----------+                |    
| |Manifest.mf|  +---------+   |
| +-----------+  | other   |   |
|                | resouce |   |
|                +---------+   |
+==============================+
關於描述文檔和清單文檔的詳細介紹,以及MIDlet屬性值代表的含義和填寫方法。請參考王森老師的文章-“利用Java撰寫手機應用-Java Application Manager篇”(《程序員》,12期,2001)。文章中寫的很明白,小弟就不一一介紹了。
MIDP的基礎篇就算是全部結束。如果時間允許,我計劃續寫MIDP高級篇。寫文章實在是一個累人的工作,但也使我獲得很多的樂趣。在此謝謝大家對我的支持

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved