使用Java 編寫手機(jī)應(yīng)用程序(續(xù))
發(fā)表時(shí)間:2024-02-13 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]█對(duì)MIDlet進(jìn)行調(diào)試 編寫PalmOS上的Spotlet時(shí),我們可以利用System.out.println()函式幫我們印出一些訊息以幫助調(diào)試,那幺在手機(jī)上的MIDlet呢? 原則上,我們還是可以利用System.out.println()函式做一些輸出。當(dāng)模擬器執(zhí)行時(shí),就會(huì)在命令列上輸出一...
█對(duì)MIDlet進(jìn)行調(diào)試
編寫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)闆]有實(shí)際的機(jī)器可以測(cè)試,因此這個(gè)問題到現(xiàn)在還不得而知,相信Motorola到時(shí)候會(huì)有完善的解決方案吧!
在Motorola J2ME SDK內(nèi)附的說明文件之中,概略地提到了調(diào)試的問題,里頭提到,往后如果我們要進(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)。
嗯,看起來能夠進(jìn)行調(diào)試,MIDlet程序的編寫應(yīng)該是很方便的事情了。
█Motorola J2ME SDK對(duì)中文的支持
相信看過RUN!PC 11月號(hào)的文章「利用Java 編寫PalmOS應(yīng)用程序基礎(chǔ)篇」的讀者,在編寫PalmOS上的Spotlet時(shí)一定會(huì)遇到中文無法正常顯示的問題。中文的問題分成兩個(gè)部分,一個(gè)是在用戶接口上的中文問題,一個(gè)是在命令列輸出(利用System.out.println()函式所做的輸出)上的中文問題,請(qǐng)大家做個(gè)小實(shí)驗(yàn),將前面我們所編寫的程序改如下:
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)過預(yù)身審核之后,我們開啟模擬器來執(zhí)行此MIDlet,底下為執(zhí)行結(jié)果:
用戶接口輸出:命令列輸出
我們從結(jié)果發(fā)現(xiàn),預(yù)設(shè)的編譯指令會(huì)讓用戶接口正常輸出中文,而命令列無法輸出正確的中文。
我們從結(jié)果發(fā)現(xiàn),預(yù)設(shè)的編譯指令會(huì)讓用戶接口正常輸出中文,而命令列無法輸出正確的中文。
接著請(qǐng)將compileAll.bat之中原本的指令
javac -O -bootclasspath ..\..\lib %COMPILECLASS%
修改為
javac –encoding ISO8859_1 -O -bootclasspath ..\..\lib %COMPILECLASS%
之后,重新編譯此MIDlet執(zhí)行結(jié)果:
用戶接口輸出: 命令列輸出
我們從結(jié)果發(fā)現(xiàn),預(yù)設(shè)的編譯指令會(huì)讓用戶接口無法正常輸出中文,而命令列卻可以輸出正確的中文。
這個(gè)結(jié)果與PalmOS上所做的中文測(cè)試結(jié)果有所不同。
當(dāng)您編寫Spotlet時(shí),如果您使用javac 。。。指令時(shí),您會(huì)發(fā)現(xiàn)模擬器上的用戶接口輸出是亂碼,可是命令列上的輸出卻可以正常輸出中文。但是如果您使用的是javac -encoding ISO8859_1 。。。指令,則CLDC內(nèi)附模擬器上的用戶接口輸出或是命令列上的輸出全部都變成亂碼,無法正常輸出中文(這個(gè)部分是因?yàn)镃LDC內(nèi)附模擬器實(shí)做的問題,造成與實(shí)際機(jī)器的結(jié)果有差異)。
總之,如果之前您所編寫的Spotlet無法在裝有中文系統(tǒng)的實(shí)際機(jī)器或POSE上正常輸出中文,請(qǐng)您也如法炮制,在編譯指令中加入-encoding ISO8859_1,就可以在實(shí)際機(jī)器或POSE上看到正常的中文字了。
會(huì)產(chǎn)生此問題的主因,主要是因?yàn)榫幾g好的Java類文件(byte code)之中,所有的文字編碼都采用UTF8。舉例來說,當(dāng)您在程序碼里用到"啟動(dòng)"這兩個(gè)中文字時(shí),
"起"這個(gè)字的Big5編碼為B1D2。
"動(dòng)"這個(gè)字的Big5編碼為B0CA。
我們會(huì)使用javac xxxx.java來編譯原始碼以產(chǎn)生類文件。其實(shí)這行指令,在繁體中文的Windows環(huán)境底下,相當(dāng)于javac -encoding "Big5" xxxx.java。也就是說,當(dāng)編譯器讀取到Big5編碼范圍的中文字時(shí),會(huì)自動(dòng)將此Big5碼經(jīng)過「Big5è Unicode 對(duì)照表」將Big5轉(zhuǎn)為Unicode,也就是說,經(jīng)過查表之后,
“起”這個(gè)字的Unicode編碼為555F。
“動(dòng)”這個(gè)字的Unicode編碼為5272。
然后再利用UTF8編碼將此Unicode轉(zhuǎn)為UTF8,儲(chǔ)存在類文件之中,因此,如果您用UltraEdit之類的文字編輯器查看類文件時(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)過測(cè)試結(jié)果,KVM似乎只有做到把UTF8讀進(jìn)來,轉(zhuǎn)換回Unicode之后就直接輸出了。少了轉(zhuǎn)回Big5的步驟,因此,操作系統(tǒng)把Unicode當(dāng)作Big5來處理,自然就找不到該碼所對(duì)應(yīng)的中文字了,也因此輸出的是一堆 ????? 的符號(hào)。這也是我們?cè)赑almOS上即使裝了中文系統(tǒng),也無法正常顯示中文的緣故。
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)類文件之中的中文變成,
"起"這個(gè)字的UTF8編碼為C2B1 C392。
"動(dòng)"這個(gè)字的UTF8編碼為C2B0 C38A。
大家可以發(fā)現(xiàn)編譯器把B1、D2、B0、CA個(gè)別當(dāng)作一個(gè)碼來處理。于是,當(dāng)KVM讀到此編碼時(shí),就會(huì)將他們轉(zhuǎn)回B1D2以及B0CA,然后KVM直接輸出,就可以正常地使用中文了。
最后總結(jié)整個(gè)問題,就筆者的推斷,CLDC內(nèi)附的模擬器再?zèng)]有使用javac –encoding ISO8859_1 xxxx.java指令之前,會(huì)在用戶接口使命令列輸出亂碼,這才是正常的結(jié)果, 而Motorola J2ME SDK內(nèi)附模擬器的用戶接口中文之所以沒問題,很可能只是因?yàn)槟M器操作的差異。因此根據(jù)KVM的輸出結(jié)果來看,很可能在實(shí)際的手機(jī)上,我們都必須加上-encoding ISO8859_1選項(xiàng)才能正確輸出中文吧!
在此特別感謝靜宜大學(xué)資管系的唐愷隆(
[email protected])同學(xué)。因?yàn)楣P者于他經(jīng)過熱烈的討論之后,我們才能對(duì)J2ME的中文問題有更深入的認(rèn)識(shí)
█支持Motorola J2ME SDK的開發(fā)工具
在編寫本文的時(shí)候,支持MIDlet開發(fā)的集成開發(fā)環(huán)境(IDE)只有Motorola J2ME SDK附帶文件之中所提到的CodeWarrior而已。相信其它廠商,如Borland,應(yīng)該也會(huì)很快地利用其產(chǎn)品JBuilder的OpenTools API來支持MIDlet的開發(fā)才對(duì),更何況Borland JBuilder目前已經(jīng)有Spotlet的解決方案了。
因?yàn)楣P者無法拿到CodeWarrior作測(cè)試,所以無法在此提供大家相關(guān)信息,相信如果有機(jī)會(huì)的話,會(huì)另外以專文向大家介紹如何利用CodeWarrior編寫MIDlet。
Motorola J2ME SDK附帶文件在附錄的部分有對(duì)利用CodeWarrior開發(fā)MIDlet做簡(jiǎn)單的介紹,相信對(duì)初學(xué)者來說,已經(jīng)相當(dāng)足夠了。
█Motorola J2ME SDK內(nèi)含的輔助開發(fā)工具
在Motorola J2ME SDK之中內(nèi)含三項(xiàng)輔助開發(fā)工具,可以便利我們的程序開發(fā)工作,它們分別是:
J2ME模擬器(J2ME Emulator)
讓您可以在您的PC上模擬Motorola將來會(huì)支持J2ME的手機(jī)裝置。如此一來就可以在PC上直接測(cè)試寫好的程序。
Bytecode驗(yàn)證器(Bytecode Verifier)
此驗(yàn)證器用來驗(yàn)證類文件(classfile)之中的bytecode不會(huì)對(duì)存儲(chǔ)器做非法的存取。并確認(rèn)載入虛擬機(jī)器的類文件所做的所有動(dòng)作皆符合Java虛擬機(jī)器規(guī)格(Java Virtual Machine Specification)。
配置編輯器(Configuration Editor)
讓您能夠建立或修改device profile。
在Motorola J2ME SDK內(nèi)附的文件之中對(duì)這三個(gè)工具有詳細(xì)的說明,筆者在此就不再贅述了。
█總結(jié)
呼!好累人,終于到了該做總結(jié)的時(shí)候了! 大家以為MIDlet就這樣結(jié)束了嗎?不! MIDlet還有許多好玩的玩意兒呢! 我們將在本系列之后的文章中為大家更深入探討MIDlet。咱們下次見。
█附錄:范例程序
Motorola J2ME SDK之中內(nèi)附許多有趣的范例,它們位于demo/midlets/目錄底下。有興趣繼續(xù)精進(jìn)的讀者可以由這些范例學(xué)到更多有關(guān)MIDlet的深入技巧,由于這些范例的執(zhí)行畫面過大,所以在本文之中就將他們省略,請(qǐng)讀者們自行參考說明文件。
這些范例程序有:
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
█網(wǎng)絡(luò)資源
◎網(wǎng)站
名稱 URL
Motorola官方網(wǎng)站 http://www.motorola.com/java/
Metrowerks(CodeWarrior) http://www.Metrowerks.com