隨筆 - 2, 文章 - 10, 評(píng)論 - 3, 引用 - 0
          數(shù)據(jù)加載中……

          利用Java 編寫(xiě)手機(jī)應(yīng)用程序 Motorola iDEN篇(轉(zhuǎn)載)

          █前言

          本文內(nèi)容的所有操作皆在Windows 200操作系統(tǒng)上經(jīng)過(guò)測(cè)試。如果您在不同的平臺(tái)上驗(yàn)證本文內(nèi)容,例如Windows 98或是Windows Me,則我們無(wú)法保證會(huì)有相同的結(jié)果。

          █簡(jiǎn)介

          不知從什幺時(shí)候開(kāi)始,我們突然感覺(jué)到周?chē)娜烁鞲鲹碛幸恢皇謾C(jī)。利用手機(jī)與別人溝通成了我們生活的一部份。北歐某些先進(jìn)國(guó)家的人民可以利用手機(jī)購(gòu)買(mǎi)自動(dòng)售貨機(jī)所出售的商品;他們也可以在從事行動(dòng)商務(wù)(m-commence) 交易時(shí)利用手機(jī)做為一種認(rèn)證工具。在日本,行動(dòng)電話的許多附加功能更是年輕人文化的一部分。即將來(lái)臨的3G,無(wú)線寬頻的美夢(mèng)帶給了人們對(duì)無(wú)線通訊未來(lái)的期待。

          然后,有些廠商開(kāi)始行銷(xiāo)它們自己生產(chǎn)的PDA,好象沒(méi)有一臺(tái)PDA在手,就不像現(xiàn)代人似的。各式各樣的PDA充斥市面,暢銷(xiāo)的與不暢銷(xiāo)的,讓人眼花撩亂。這時(shí)產(chǎn)生了一個(gè)大問(wèn)題--要我們同時(shí)攜帶手機(jī)和PDA是一件很麻煩的事情-就算它們都還算輕薄短小。如果可以把手機(jī)和PDA合而為一豈不是更方便嗎? 于是聽(tīng)到消費(fèi)者心聲的廠商,開(kāi)始有推出手機(jī)和PDA合而為一的產(chǎn)品,從NOKIA 9000、Motorola A6188(太極),到最近要推出的Ericsson R380、NOKIA 9210,都是手機(jī)與PDA結(jié)合的例子,雖然因?yàn)槭蹆r(jià)的關(guān)系,但是這些產(chǎn)品仍然是許多人夢(mèng)寐以求的高階產(chǎn)品。

          盡管有了PDA與手機(jī)結(jié)合的產(chǎn)品出現(xiàn),我們?nèi)匀挥X(jué)得有所不足,我想大家一定發(fā)現(xiàn)了,就是應(yīng)用程序的不足,雖然手機(jī)和PDA 結(jié)合了,可是這些產(chǎn)品上的PDA功能看起來(lái)似乎是死的。我們可以任意在PalmOS、Windows CE、EPOC等PDA上使用C/C++或是Java編寫(xiě)這些平臺(tái)上的應(yīng)用程序,但是卻從未有過(guò)機(jī)會(huì)將我們寫(xiě)好的程序下載到這些手機(jī)上執(zhí)行(即使有些手機(jī)的PDA也是使用EPOC,如Ericsson R380)。

          相信廠商也聽(tīng)到我們這些喜歡到處寫(xiě)程序的工程師的心聲了,所以從2000年年底開(kāi)始,即將陸陸續(xù)續(xù)有許多支持Java的手機(jī)即將推出,當(dāng)然,這些廠商也提供了在手機(jī)上開(kāi)發(fā)程序的SDK,我們終于可以在手機(jī)上面寫(xiě)些小程序自?shī)柿?這是以前等了很久的美夢(mèng)。

          手機(jī)平臺(tái)的多樣性與復(fù)雜性,和PDA比較起來(lái)可以說(shuō)是有過(guò)之而無(wú)不及,于是大家就可以知道 - 哈!又是Java派上用場(chǎng)的時(shí)候了。我們都知道在瀏覽器上執(zhí)行的Java程序叫做Applet,在PalmOS上執(zhí)行的Java程序叫做Spotlet,然而在手機(jī)上執(zhí)行的應(yīng)用程序我們稱做MIDlet,相信對(duì)大家來(lái)說(shuō)都是一個(gè)陌生的名詞,這也就是本篇文章所要介紹的主角。

          支持Java的手機(jī)大廠目前已知有NOKIA (預(yù)計(jì)在2001年年初推出一款支持Java的手機(jī)NOKIA 9210)、Motorola(會(huì)先在支持integrated Digital enhanced network(iDen)網(wǎng)絡(luò)的手機(jī)上支持Java,然后再推出支持Java的GSM手機(jī),該公司的手機(jī)大致會(huì)在2002年前全部支持Java)以及NTT DoCoMo(將在明年第二季度左右推出支持Java的手機(jī))。

          雖然這些大公司都準(zhǔn)備支持Java,不過(guò)在決定編寫(xiě)本文時(shí),只有Motorola將其SDK開(kāi)放于網(wǎng)站上供程序開(kāi)發(fā)者下載測(cè)試,所以本文內(nèi)容都是根據(jù)Motorola J2ME SDK所編寫(xiě)。又由于這些手機(jī)市面上無(wú)法取得,所以我們的程序都是在SDK內(nèi)附的模擬器中執(zhí)行,相信最后這些手機(jī)上市時(shí),我們所編寫(xiě)的MIDlet應(yīng)該會(huì)很容易并成功地在Motorola的手機(jī)上執(zhí)行才對(duì)。

          █如何取得Motorola J2ME SDK

          我們要做的第一件事情當(dāng)然還是要先取得SDK羅!
          請(qǐng)直接到https://commerce.motorola.com/idenonline/ideveloper/下載Motorola J2ME SDK Drop 7。如果您不是iDEN? Developer的會(huì)員,請(qǐng)先在網(wǎng)絡(luò)上注冊(cè)(免費(fèi))。注冊(cè)成功之后,Motorola會(huì)將密碼寄到您的email信箱之中,然后使用該密碼登入網(wǎng)頁(yè)上的My Development Center。進(jìn)入之后選擇網(wǎng)頁(yè)上頭的TOOLS & RESOURCES以進(jìn)入可下載的開(kāi)發(fā)工具的網(wǎng)頁(yè),請(qǐng)選擇Motorola J2ME SDK Components Developer Edition, Drop 7.0下方的下載超連結(jié)以下載SDK,整個(gè)SDK的大小約為3 MB左右。

          請(qǐng)注意下載前的Download Page for Motorola J2ME? SDK安裝說(shuō)明,里頭會(huì)告訴你安裝密碼,請(qǐng)先行記下。稍后當(dāng)您在您的電腦上安裝Motorola J2ME SDK的時(shí)候,會(huì)詢問(wèn)您安裝密碼,所以請(qǐng)務(wù)必記下該密碼。

          █Motorola J2ME SDK的安裝

          安裝需求
          根據(jù)官方需求,安裝Motorola J2ME SDK的基本配備為:
          Pentium 100 MHz微處理器
          64 MB RAM
          Windows NT WorkStation 4.0配合Service Pack 3 / Win98
          (本文是在Windows 2000 Professional中文版上測(cè)試)
          約6 MB的硬盤(pán)空間
          Java 2 SDK 1.2.2
          (本文使用Java 2 SDK 1.3.0_01作測(cè)試)

          安裝Motorola J2ME SDK
          要安裝新版Motorola J2ME SDK之前,請(qǐng)先確認(rèn)您已經(jīng)將舊版的Motorola J2ME SDK完全刪除。您可以由控制臺(tái)里頭的 「新增/刪除程序」的功能刪除舊版Motorola J2ME SDK。之后再將舊版Motorola J2ME SDK安裝所在路徑清除即可。
          解開(kāi)您從Motorola網(wǎng)站上下載的ZIP文件,您會(huì)看到一個(gè)名為Motorola_SDK.exe的文件,雙擊此文件即可開(kāi)始安裝動(dòng)作。請(qǐng)注意,在安裝時(shí)系統(tǒng)會(huì)要求您輸入密碼,請(qǐng)輸入之前所紀(jì)錄的安裝密碼即可。

          █Motorola J2ME SDK目錄結(jié)構(gòu)

          當(dāng)您成功地安裝Motorola J2ME SDK之后,其目錄結(jié)構(gòu)如下圖:



          █MIDlet程序結(jié)構(gòu)

          在手機(jī)上執(zhí)行的程序我們統(tǒng)稱MIDlet,其程序結(jié)構(gòu)很簡(jiǎn)單,與大家熟悉的Applet結(jié)構(gòu)有異曲同工之妙。
          每一個(gè)MIDlet程序都必須繼承自javax.microedition.midlet.MIDlet類(lèi)別,并實(shí)做三個(gè)函式,它們分別是:

          protected void startApp()
          protected void pauseApp()
          protected void destroyApp(Boolean unconditional)
          而一個(gè)MIDlet程序的起始與結(jié)束之流程我們以下圖來(lái)表示:

          █編寫(xiě)并編譯MIDlet

          請(qǐng)先到您的Motorola J2ME SDK安裝目錄下的demo\midlets目錄底下新建一個(gè)名為HelloMIDlet.java的文件,其內(nèi)容為:

          HelloMIDlet.java
          import javax.microedition.lcdui.*;
          import javax.microedition.midlet.*;

          public class HelloMIDlet extends MIDlet
          {
          HelloMIDlet()
          {
          }

          protected void startApp() throws MIDletStateChangeException
          {
          }

          protected void pauseApp()
          {
          }

          protected void destroyApp(boolean unconditional)
          throws MIDletStateChangeException
          {
          }
          }
          在demo\midlets目錄之中您會(huì)看到一個(gè)名為compileAll.bat的批處理文件,前面有提到,這個(gè)批處理文件除了可以幫助您編譯所有內(nèi)附范例程序之外,還可以簡(jiǎn)化您自己所編寫(xiě)的MIDlet之編譯流程。
          請(qǐng)?jiān)诿盍幸暣拜斎? compileAll HelloMIDlet.java
          如果成功編譯,屏幕上輸出的結(jié)果如下圖所示:




          從屏幕上的輸出,您可以發(fā)現(xiàn),要讓MIDlet可以在手機(jī)上執(zhí)行,大體上還是要經(jīng)過(guò)兩個(gè)動(dòng)作(與Spotlet相似),分別是編譯(compiling)以及預(yù)先審核(Preverifying)。
          有關(guān)預(yù)先審核這個(gè)動(dòng)作,筆者已經(jīng)在RUN!PC 11月號(hào)的文章「利用Java 編寫(xiě)PalmOS應(yīng)用程序基礎(chǔ)篇」之中有向讀者們提過(guò),如果對(duì)這個(gè)方面有所疑問(wèn)的朋友,請(qǐng)?jiān)賹⒛腞UN!PC 11月號(hào)翻出來(lái)復(fù)習(xí)一下吧!

          從這個(gè)簡(jiǎn)短的MIDlet制作流程里頭,相信大家可以發(fā)現(xiàn),比起純粹用Sun的CLDC編寫(xiě)能在KVM上執(zhí)行的Spotlet要簡(jiǎn)單上許多。原因是compileAll.bat這個(gè)批處理文件幫我們做掉大部分dirty work。
          那幺,如果您寫(xiě)好的程序并非放在demo\midlets目錄之中,是否就無(wú)法編譯了? 從compileAll.bat里頭,我們可以發(fā)現(xiàn)它幫我們完成上述兩項(xiàng)工作的指令。如果我們寫(xiě)好的程序放在demo\midlets目錄以外的地方,您可以執(zhí)行下面的指令,您仍然可以成功地制作MIDlet:
          (我們假設(shè)您的Motorola J2ME SDK安裝在D:\MotoSDK目錄之中,并將您自行編寫(xiě)的HelloMIDlet.java置于d:\jdk1.3.0_01\my目錄之中。同時(shí)我們假設(shè)您在d:\jdk1.3.0_01\my目錄底下執(zhí)行下面指令。)
          編譯:

          javac -O -bootclasspath d:\MotoSDK\lib HelloMIDlet.java
          注意: -bootclasspath指向類(lèi)函數(shù)庫(kù)的所在位置。

          預(yù)先審核:

          d:\MotoSDK\bin\preverifier -classpath d:\MotoSDK\lib;. -d . HelloMIDlet
          注意:
          1 . -classpath指向類(lèi)函數(shù)庫(kù)的所在位置,也要指向我們所編寫(xiě)的MIDlet所在的位置。
          2 .–d指向您希望預(yù)先編譯類(lèi)文件產(chǎn)生之后所放置的路徑,如果寫(xiě)"."表示本目錄,會(huì)覆蓋掉原先未經(jīng)過(guò)預(yù)先編譯的類(lèi)文件。如果您沒(méi)有指定,則預(yù)設(shè)值為".\output"目錄。

          當(dāng)然,如果您嫌自己手動(dòng)操作很麻煩,您可以將compileAll.bat復(fù)制到其它目錄之中,并更改其編譯指令與預(yù)先審核指令之中和類(lèi)函數(shù)庫(kù)有關(guān)的相關(guān)設(shè)定即可。
          提到compileAll.bat,順便向各位讀者說(shuō)明一下,在前面有提到,compileAll.bat可以幫助您編譯所有位于demo\midlets目錄下的范例程序,您只要在命列列下直接輸入: compileAll即可。compileAll.bat會(huì)自動(dòng)當(dāng)您編譯的package有以下幾項(xiàng):
          com.mot.j2me.midlets.bounce
          com.mot.j2me.midlets.imagetests
          com.mot.j2me.midlets.paddleball
          com.mot.j2me.midlets.scribble
          com.mot.j2me.midlets.tests
          com.mot.j2me.midlets.tutorials
          如果您希望compileAll.bat自動(dòng)幫您編譯其它package底下的程序,請(qǐng)您開(kāi)啟compileAll.bat,修改其COMPILECLASS環(huán)境變數(shù)的設(shè)定即可。

          █修改并執(zhí)行MIDlet

          寫(xiě)好程序之后,大家最希望的事情當(dāng)然就是讓它在手機(jī)上執(zhí)行,不過(guò)由于目前大家無(wú)法取得Motorola這些支持Java的手機(jī),所以我們只能在Motorola J2ME SDK內(nèi)附的模擬器上執(zhí)行我們寫(xiě)好的MIDlet。相信手機(jī)正式推出時(shí),應(yīng)該可以順利地在手機(jī)上執(zhí)行。底下筆者將告訴您如何使用Motorola J2ME SDK內(nèi)附的模擬器來(lái)測(cè)試您所編寫(xiě)的MIDlet。
          在這之前,由于之前我們所編寫(xiě)的范例程序只是簡(jiǎn)單的MIDlet空殼,我們必須讓它能夠在模擬器上顯示出一些信息才可以,因此請(qǐng)修改上一個(gè)程序范例,使它的內(nèi)容如下:
          HelloMIDlet.java
          import javax.microedition.lcdui.*;
          import javax.microedition.midlet.*;

          public class HelloMIDlet extends MIDlet
          {
          private Display firstDisplay ;
          private Form firstForm ;
          HelloMIDlet()
          {
          firstDisplay = Display.getDisplay(this) ;
          firstForm = new Form("Hello MIDlet") ;
          StringItem firstStrItem = new StringItem("Hello","MIDlet") ;
          firstForm.append(firstStrItem) ;
          }

          protected void startApp() throws MIDletStateChangeException
          {
          firstDisplay.setCurrent(firstForm) ;
          }

          protected void pauseApp()
          {
          }

          protected void destroyApp(boolean unconditional)
          throws MIDletStateChangeException
          {
          }
          }
          請(qǐng)將此文件放置在\demo\midlets目錄下。編譯完成之后,請(qǐng)將目錄切換到scripts子目錄之中,您會(huì)在此目錄里發(fā)現(xiàn)一些寫(xiě)好的批處理文件。請(qǐng)?jiān)谠撃夸浵聢?zhí)行這些批處理文件指令以啟動(dòng)模擬器。執(zhí)行的指令與執(zhí)行結(jié)果如下所示:

          指令: runEmul HelloMIDlet
          輸出結(jié)果:


          指令: runMotoi1000 HelloMIDlet
          輸出結(jié)果:


          指令: runMotoiDEN HelloMIDlet
          輸出結(jié)果 :


          指令: runStarTac HelloMIDlet
          輸出結(jié)果:


          指令: runMyDevice HelloMIDlet
          輸出結(jié)果
          Error loading property file: C:/properties/mydevice.props (系統(tǒng)找不到指定的路徑。)會(huì)出現(xiàn)錯(cuò)誤信息是因?yàn)槟鷽](méi)有指定屬于是用者自訂的手機(jī)外觀的緣故,后面將會(huì)教您如何設(shè)定用戶自訂的手機(jī)外觀。



          如果我們將寫(xiě)好的程序放在demo\midlets目錄以外的地方,您可以執(zhí)行下面的指令,仍然可以成功地啟動(dòng)模擬器并執(zhí)行MIDlet:
          (我們假設(shè)您的Motorola J2ME SDK安裝在D:\MotoSDK目錄之中,并將您自行編寫(xiě)的HelloMIDlet.java置于d:\jdk1.3.0_01\my目錄之中。同時(shí)我們假設(shè)您在d:\jdk1.3.0_01\my目錄底下執(zhí)行下面指令。)

          執(zhí)行一般模擬器 java -Djava.library.path=d:\MotoSDK\lib
          -classpath d:\MotoSDK\bin\Emulator.jar;d:\MotoSDK\bin\ConfigTool.jar com.mot.tools.j2me.emulator.Emulator

          -classpath.;d:\MotoSDK\lib javax.microedition.midlet.AppManager HelloMIDlet

          -JSA 1 1

          請(qǐng)注意:
          第一個(gè)-classpath設(shè)定,-classpath與路徑名稱之間有空格。
          第二個(gè)-classpath設(shè)定,-classpath與路徑名稱之間沒(méi)有空格。



          執(zhí)行模擬器并套用i1000手機(jī)外觀
          java -Djava.library.path=d:\MotoSDK\lib
          -classpath d:\MotoSDK\bin\Emulator.jar;d:\MotoSDK\bin\ConfigTool.jar com.mot.tools.j2me.emulator.Emulator

          -classpath.;d:\MotoSDK\lib
          -deviceFile resources\Motorolai1000.props
          javax.microedition.midlet.AppManager

          HelloMIDlet
          -JSA 1 1

          請(qǐng)注意:
          第一個(gè)-classpath設(shè)定,-classpath與路徑名稱之間有空格。
          第二個(gè)-classpath設(shè)定,-classpath與路徑名稱之間沒(méi)有空格。



          執(zhí)行模擬器并套用iDEN手機(jī)外觀 java -Djava.library.path=d:\MotoSDK\lib
          -classpath d:\MotoSDK\bin\Emulator.jar;d:\MotoSDK\bin\ConfigTool.jar com.mot.tools.j2me.emulator.Emulator

          -classpath.;d:\MotoSDK\lib
          -deviceFile resources\MotorolaiDENPlatform.props
          javax.microedition.midlet.AppManager

          HelloMIDlet
          -JSA 1 1
          請(qǐng)注意:
          第一個(gè)-classpath設(shè)定,-classpath與路徑名稱之間有空格。
          第二個(gè)-classpath設(shè)定,-classpath與路徑名稱之間沒(méi)有空格。



          執(zhí)行模擬器并套用StarTac手機(jī)外觀 java -Djava.library.path=d:\MotoSDK\lib
          -classpath d:\MotoSDK\bin\Emulator.jar;d:\MotoSDK\bin\ConfigTool.jar com.mot.tools.j2me.emulator.Emulator

          -classpath.;d:\MotoSDK\lib
          -deviceFile resources\StarTac.props
          javax.microedition.midlet.AppManager

          HelloMIDlet
          -JSA 1 1
          請(qǐng)注意:
          第一個(gè)-classpath設(shè)定,-classpath與路徑名稱之間有空格。
          第二個(gè)-classpath設(shè)定,-classpath與路徑名稱之間沒(méi)有空格。



          執(zhí)行模擬器并套用用戶自訂手機(jī)外觀 java -Djava.library.path=d:\MotoSDK\lib
          -classpath d:\MotoSDK\bin\Emulator.jar;d:\MotoSDK\bin\ConfigTool.jar com.mot.tools.j2me.emulator.Emulator

          -classpath.;d:\MotoSDK\lib
          -deviceFile <您的props文件所在的絕對(duì)路徑>javax.microedition.midlet.AppManager

          HelloMIDlet
          -JSA 1 1
          請(qǐng)注意:
          第一個(gè)-classpath設(shè)定,-classpath與路徑名稱之間有空格。
          第二個(gè)-classpath設(shè)定,-classpath與路徑名稱之間沒(méi)有空格。
          如果您將您的props文件放在d:\MotoSDK\bin的resources目錄之下,則上述指令只要改成:-deviceFile resources\<您的props文件名>



          注意,當(dāng)您您直接使用上述指令啟動(dòng)模擬器,如果出現(xiàn)底下錯(cuò)誤信息:
          Error loading property file: resources/defaultdevice.props (系統(tǒng)找不到指定的路徑。)
          這是因?yàn)槟鷽](méi)有將d:\MotoSDK\bin目錄下的resources子目錄復(fù)制到d:\JDK1.3.0_01\my目錄之下的緣故。

          █對(duì)MIDlet進(jìn)行調(diào)試

          編寫(xiě)PalmOS上的Spotlet時(shí),我們可以利用System.out.println()函式幫我們印出一些訊息以幫助調(diào)試,那幺在手機(jī)上的MIDlet呢? 原則上,我們還是可以利用System.out.println()函式做一些輸出。當(dāng)模擬器執(zhí)行時(shí),就會(huì)在命令列上輸出一些訊息。
          另外,在PalmOS上,有KVMutil.prc可以幫助我們紀(jì)錄程序所輸出的訊息。那手機(jī)上呢? 因?yàn)闆](méi)有實(shí)際的機(jī)器可以測(cè)試,因此這個(gè)問(wèn)題到現(xiàn)在還不得而知,相信Motorola到時(shí)候會(huì)有完善的解決方案吧!
          在Motorola J2ME SDK內(nèi)附的說(shuō)明文件之中,概略地提到了調(diào)試的問(wèn)題,里頭提到,往后如果我們要進(jìn)行機(jī)上調(diào)試(on-device debugging)的話,必須要滿足幾個(gè)條件:

          機(jī)器本身要具備調(diào)試相關(guān)功能,并與KDWP(Kvm Debug Wire Protocol)兼容。因?yàn)檎{(diào)試時(shí),調(diào)試工具需要利用KDWP和機(jī)器上交談以取得調(diào)試信息。
          制造廠商本身要提供下載MIDlet到手機(jī)上以進(jìn)行調(diào)試的方法。
          提供對(duì)MIDlet調(diào)試的工具,必須支持手機(jī)在利用KDWP調(diào)試時(shí)所使用的傳輸接口(例如串行口或UDP)。
          嗯,看起來(lái)能夠進(jìn)行調(diào)試,MIDlet程序的編寫(xiě)應(yīng)該是很方便的事情了。

          █Motorola J2ME SDK對(duì)中文的支持

          相信看過(guò)RUN!PC 11月號(hào)的文章「利用Java 編寫(xiě)PalmOS應(yīng)用程序基礎(chǔ)篇」的讀者,在編寫(xiě)PalmOS上的Spotlet時(shí)一定會(huì)遇到中文無(wú)法正常顯示的問(wèn)題。中文的問(wèn)題分成兩個(gè)部分,一個(gè)是在用戶接口上的中文問(wèn)題,一個(gè)是在命令列輸出(利用System.out.println()函式所做的輸出)上的中文問(wèn)題,請(qǐng)大家做個(gè)小實(shí)驗(yàn),將前面我們所編寫(xiě)的程序改如下:
          HelloMIDlet.java
          import javax.microedition.lcdui.*;
          import javax.microedition.midlet.*;

          public class HelloMIDlet extends MIDlet
          {
          private Display firstDisplay ;
          private Form firstForm ;
          HelloMIDlet()
          {
          firstDisplay = Display.getDisplay(this) ;
          firstForm = new Form("哈羅!MIDlet") ;
          StringItem firstStrItem = new StringItem("哈羅","米德列特") ;
          firstForm.append(firstStrItem) ;
          System.out.println("MIDlet啟動(dòng)") ;
          }

          protected void startApp() throws MIDletStateChangeException
          {
          firstDisplay.setCurrent(firstForm) ;
          }

          protected void pauseApp()
          {
          }

          protected void destroyApp(boolean unconditional)
          throws MIDletStateChangeException
          {
          }
          }
          將本MIDlet編譯并經(jīng)過(guò)預(yù)身審核之后,我們開(kāi)啟模擬器來(lái)執(zhí)行此MIDlet,底下為執(zhí)行結(jié)果:


          用戶接口輸出:


          命令列輸出:


          我們從結(jié)果發(fā)現(xiàn),預(yù)設(shè)的編譯指令會(huì)讓用戶接口正常輸出中文,而命令列無(wú)法輸出正確的中文。

          接著請(qǐng)將compileAll.bat之中原本的指令
          javac -O -bootclasspath ..\..\lib %COMPILECLASS%
          修改為
          javac –encoding ISO8859_1 -O -bootclasspath ..\..\lib %COMPILECLASS%
          之后,重新編譯此MIDlet執(zhí)行結(jié)果:

          用戶接口輸出:


          命令列輸出 :



          這個(gè)結(jié)果與PalmOS上所做的中文測(cè)試結(jié)果有所不同。
          當(dāng)您編寫(xiě)Spotlet時(shí),如果您使用javac 。。。指令時(shí),您會(huì)發(fā)現(xiàn)模擬器上的用戶接口輸出是亂碼,可是命令列上的輸出卻可以正常輸出中文。但是如果您使用的是javac -encoding ISO8859_1 。。。指令,則CLDC內(nèi)附模擬器上的用戶接口輸出或是命令列上的輸出全部都變成亂碼,無(wú)法正常輸出中文(這個(gè)部分是因?yàn)镃LDC內(nèi)附模擬器實(shí)做的問(wèn)題,造成與實(shí)際機(jī)器的結(jié)果有差異)。
          總之,如果之前您所編寫(xiě)的Spotlet無(wú)法在裝有中文系統(tǒng)的實(shí)際機(jī)器或POSE上正常輸出中文,請(qǐng)您也如法炮制,在編譯指令中加入-encoding ISO8859_1,就可以在實(shí)際機(jī)器或POSE上看到正常的中文字了。

          會(huì)產(chǎn)生此問(wèn)題的主因,主要是因?yàn)榫幾g好的Java類(lèi)文件(byte code)之中,所有的文字編碼都采用UTF8。舉例來(lái)說(shuō),當(dāng)您在程序碼里用到"啟動(dòng)"這兩個(gè)中文字時(shí),
          "起"這個(gè)字的Big5編碼為B1D2。
          "動(dòng)"這個(gè)字的Big5編碼為B0CA。
          我們會(huì)使用javac xxxx.java來(lái)編譯原始碼以產(chǎn)生類(lèi)文件。其實(shí)這行指令,在繁體中文的Windows環(huán)境底下,相當(dāng)于javac -encoding "Big5" xxxx.java。也就是說(shuō),當(dāng)編譯器讀取到Big5編碼范圍的中文字時(shí),會(huì)自動(dòng)將此Big5碼經(jīng)過(guò)「Big5è Unicode 對(duì)照表」將Big5轉(zhuǎn)為Unicode,也就是說(shuō),經(jīng)過(guò)查表之后,
          “起”這個(gè)字的Unicode編碼為555F。
          “動(dòng)”這個(gè)字的Unicode編碼為5272。
          然后再利用UTF8編碼將此Unicode轉(zhuǎn)為UTF8,儲(chǔ)存在類(lèi)文件之中,因此,如果您用UltraEdit之類(lèi)的文字編輯器查看類(lèi)文件時(shí),您會(huì)看到,
          "起"這個(gè)字的UTF8編碼為E5959F。
          "動(dòng)"這個(gè)字的UTF8編碼為E58B95。

          接著,當(dāng)我們?cè)诔绦驁?zhí)行時(shí)如果要將中文輸出,則JVM會(huì)負(fù)責(zé)讀進(jìn)UTF8碼,然后將其轉(zhuǎn)回Unicode,最后依據(jù)您所使用的系統(tǒng)環(huán)境預(yù)設(shè)的編碼轉(zhuǎn)回Big5,再輸出至屏幕上。
          可是經(jīng)過(guò)測(cè)試結(jié)果,KVM似乎只有做到把UTF8讀進(jìn)來(lái),轉(zhuǎn)換回Unicode之后就直接輸出了。少了轉(zhuǎn)回Big5的步驟,因此,操作系統(tǒng)把Unicode當(dāng)作Big5來(lái)處理,自然就找不到該碼所對(duì)應(yīng)的中文字了,也因此輸出的是一堆 ????? 的符號(hào)。這也是我們?cè)赑almOS上即使裝了中文系統(tǒng),也無(wú)法正常顯示中文的緣故。
          OK,既然知道KVM只幫我們做了一半的工作,那事情就好辦了,我們只要讓UTF8轉(zhuǎn)回之后,仍然保有Big5的編碼方式即可,于是我們使用指令javac -encoding ISO8859_1 xxxx.java,請(qǐng)編譯器不要將程序碼中中文Big5編碼的兩個(gè)byte視為一體(因?yàn)橐暈橐惑w就會(huì)引發(fā)查詢Big5 è Unicode對(duì)照表的工作),只要將中文當(dāng)作是普通的西歐字母字集即可,因此,當(dāng)我們使用了上述指令,您會(huì)發(fā)現(xiàn)類(lèi)文件之中的中文變成,
          "起"這個(gè)字的UTF8編碼為C2B1 C392。
          "動(dòng)"這個(gè)字的UTF8編碼為C2B0 C38A。
          大家可以發(fā)現(xiàn)編譯器把B1、D2、B0、CA個(gè)別當(dāng)作一個(gè)碼來(lái)處理。于是,當(dāng)KVM讀到此編碼時(shí),就會(huì)將他們轉(zhuǎn)回B1D2以及B0CA,然后KVM直接輸出,就可以正常地使用中文了。

          最后總結(jié)整個(gè)問(wèn)題,就筆者的推斷,CLDC內(nèi)附的模擬器再?zèng)]有使用javac –encoding ISO8859_1 xxxx.java指令之前,會(huì)在用戶接口使命令列輸出亂碼,這才是正常的結(jié)果, 而Motorola J2ME SDK內(nèi)附模擬器的用戶接口中文之所以沒(méi)問(wèn)題,很可能只是因?yàn)槟M器操作的差異。因此根據(jù)KVM的輸出結(jié)果來(lái)看,很可能在實(shí)際的手機(jī)上,我們都必須加上-encoding ISO8859_1選項(xiàng)才能正確輸出中文吧!

          在此特別感謝靜宜大學(xué)資管系的唐愷隆(kailung.tang@msa.hinet.net)同學(xué)。因?yàn)楣P者于他經(jīng)過(guò)熱烈的討論之后,我們才能對(duì)J2ME的中文問(wèn)題有更深入的認(rèn)識(shí)

          █支持Motorola J2ME SDK的開(kāi)發(fā)工具

          在編寫(xiě)本文的時(shí)候,支持MIDlet開(kāi)發(fā)的集成開(kāi)發(fā)環(huán)境(IDE)只有Motorola J2ME SDK附帶文件之中所提到的CodeWarrior而已。相信其它廠商,如Borland,應(yīng)該也會(huì)很快地利用其產(chǎn)品JBuilder的OpenTools API來(lái)支持MIDlet的開(kāi)發(fā)才對(duì),更何況Borland JBuilder目前已經(jīng)有Spotlet的解決方案了。
          因?yàn)楣P者無(wú)法拿到CodeWarrior作測(cè)試,所以無(wú)法在此提供大家相關(guān)信息,相信如果有機(jī)會(huì)的話,會(huì)另外以專文向大家介紹如何利用CodeWarrior編寫(xiě)MIDlet。
          Motorola J2ME SDK附帶文件在附錄的部分有對(duì)利用CodeWarrior開(kāi)發(fā)MIDlet做簡(jiǎn)單的介紹,相信對(duì)初學(xué)者來(lái)說(shuō),已經(jīng)相當(dāng)足夠了。

          █Motorola J2ME SDK內(nèi)含的輔助開(kāi)發(fā)工具

          在Motorola J2ME SDK之中內(nèi)含三項(xiàng)輔助開(kāi)發(fā)工具,可以便利我們的程序開(kāi)發(fā)工作,它們分別是:

          J2ME模擬器(J2ME Emulator)
          讓您可以在您的PC上模擬Motorola將來(lái)會(huì)支持J2ME的手機(jī)裝置。如此一來(lái)就可以在PC上直接測(cè)試寫(xiě)好的程序。
          Bytecode驗(yàn)證器(Bytecode Verifier)
          此驗(yàn)證器用來(lái)驗(yàn)證類(lèi)文件(classfile)之中的bytecode不會(huì)對(duì)存儲(chǔ)器做非法的存取。并確認(rèn)載入虛擬機(jī)器的類(lèi)文件所做的所有動(dòng)作皆符合Java虛擬機(jī)器規(guī)格(Java Virtual Machine Specification)。
          配置編輯器(Configuration Editor)
          讓您能夠建立或修改device profile。
          在Motorola J2ME SDK內(nèi)附的文件之中對(duì)這三個(gè)工具有詳細(xì)的說(shuō)明,筆者在此就不再贅述了。

          █總結(jié)

          呼!好累人,終于到了該做總結(jié)的時(shí)候了! 大家以為MIDlet就這樣結(jié)束了嗎?不! MIDlet還有許多好玩的玩意兒呢! 我們將在本系列之后的文章中為大家更深入探討MIDlet。咱們下次見(jiàn)。

          █附錄:范例程序

          Motorola J2ME SDK之中內(nèi)附許多有趣的范例,它們位于demo/midlets/目錄底下。有興趣繼續(xù)精進(jìn)的讀者可以由這些范例學(xué)到更多有關(guān)MIDlet的深入技巧,由于這些范例的執(zhí)行畫(huà)面過(guò)大,所以在本文之中就將他們省略,請(qǐng)讀者們自行參考說(shuō)明文件。
          這些范例程序有:
          Bounce
          com.mot.j2me.midlets.bounce.Bounce
          PaddleBall
          com.mot.j2me.midlets.paddleball.PaddleBall
          Scribble
          com.mot.j2me.midlets.scribble.Scribble
          FontDemo
          com.mot.j2me.midlets.tutorials.FontDemo
          GraphicsDemo
          com.mot.j2me.midlets.tutorials.GraphicsDemo
          RecordStoreDemo
          com.mot.j2me.midlets.tutorials.RecordStoreDemo
          UDP Tutorial Application
          com.mot.j2me.midlets.tutorials.UDPReceive
          AlertTest
          com.mot.j2me.midlets.tests.AlertTest
          ChoiceGroupTest
          com.mot.j2me.midlets.tests.ChoiceGroupTest
          DateFieldTest
          com.mot.j2me.midlets.tests.DateFieldTest
          FormTest
          com.mot.j2me.midlets.tests.FormTest
          GaugeTest
          com.mot.j2me.midlets.tests.GaugeTest
          KeyEventsTest
          com.mot.j2me.midlets.tests.KeyEventsTest
          TextBoxTest
          com.mot.j2me.midlets.tests.TextBoxTest
          TextFieldTest
          com.mot.j2me.midlets.tests.TextFieldTest
          TickerTest
          com.mot.j2me.midlets.tests.TickerTest

          posted on 2006-02-04 14:27 Alex 閱讀(143) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): 轉(zhuǎn)載

          主站蜘蛛池模板: 古交市| 小金县| 措美县| 大足县| 福安市| 贞丰县| 肇东市| 大余县| 思茅市| 察雅县| 商洛市| 呼图壁县| 宁河县| 襄樊市| 白朗县| 徐闻县| 布拖县| 黑山县| 隆昌县| 绍兴市| 东台市| 靖州| 腾冲县| 望江县| 社会| 遵义县| 北票市| 江油市| 晋城| 清丰县| 建阳市| 道孚县| 余姚市| 南充市| 祁连县| 浦东新区| 汶上县| 公安县| 若尔盖县| 广河县| 新巴尔虎左旗|