<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>


    路慢慢其休遠(yuǎn)兮,吾將上下而求素
    posts - 17,comments - 7,trackbacks - 0
    J2ME中需要的Java基礎(chǔ)知識(shí)
           現(xiàn)在有大部分人,都是從零開始學(xué)J2ME的,學(xué)習(xí)J2ME的時(shí)候,總是從Java基礎(chǔ)開始學(xué)習(xí),而且現(xiàn)在講Java基礎(chǔ)的書籍中都是以J2SE來(lái)講基礎(chǔ),這就給學(xué)習(xí)造成了一些不必要的麻煩,下面將J2ME中用到的和不需要的Java基礎(chǔ)知識(shí)做一個(gè)簡(jiǎn)單的說(shuō)明。
           J2ME中使用到的Java基礎(chǔ)知識(shí):
        1、Java語(yǔ)法基礎(chǔ):包括基本數(shù)據(jù)類型、關(guān)鍵字、運(yùn)算符等等
        2、面向?qū)ο蟮乃枷耄侯惡蛯?duì)象的概念,繼承和多態(tài)等等。
        3、異常處理
        4、多線程
      J2ME中沒有用到的Java基礎(chǔ)知識(shí):
        1、JDK中javac和java命令的使用
        2、Java基礎(chǔ)中的很多類在J2ME中沒有,或者類中的方法做了大量的精簡(jiǎn)。所以建議在J2ME中熟悉類庫(kù)。
        3、Applet、AWT、Swing這些知識(shí)在J2ME中根本使用不到。
      簡(jiǎn)單說(shuō)這么多,希望學(xué)J2ME的朋友們能少走一些彎路,不足之處希望大家積極指正和補(bǔ)充。

    二、J2ME中暫時(shí)無(wú)法完成的功能
      列一些J2ME中暫時(shí)無(wú)法完成的功能,希望大家能積極補(bǔ)充:
        1、在手機(jī)中不更改代碼實(shí)現(xiàn)移植,主要指游戲。
        2、動(dòng)態(tài)修改按鈕文字。
        3、在Canvas上接受中文輸入。
        4、操作本地資源、例如地址本、已收短信息等。
        5、制作破壞性的手機(jī)病毒。
        6、其他等待大家來(lái)補(bǔ)充。

    三、J2ME的跨平臺(tái)性
      J2ME技術(shù)源于Java,所以也具有JVM的優(yōu)勢(shì),可以在支持Java的平臺(tái)上進(jìn)行移植,但是現(xiàn)在的J2ME技術(shù)在跨平臺(tái)上卻做的很糟糕,我們來(lái)簡(jiǎn)單看一下原因:
      1、手機(jī)的屏幕尺寸不一:
      這個(gè)主要在界面制作上。如果你使用的是高級(jí)用戶界面,比如你做的是應(yīng)用開發(fā)或者用戶登陸、用戶注冊(cè)這樣的通用功能時(shí),一般沒有什么問(wèn)題。
      如果你使用的是低級(jí)用戶界面,比如你做的是游戲,那么你就需要考慮這個(gè)問(wèn)題了。
      2、廠商的擴(kuò)展API不統(tǒng)一:
      例如Nokia的擴(kuò)展API類庫(kù)UI系列,在別的手機(jī)上或者沒有實(shí)現(xiàn),或者包名不同等等。
      3、手機(jī)平臺(tái)上實(shí)現(xiàn)的bug:
      例如Nokia的7650在實(shí)現(xiàn)雙緩沖上有bug,那么在這種機(jī)型上運(yùn)行的軟件就不能使用雙緩沖。其他NOKIA上的一些bug,可以參看:http://blog.csdn.net/Mailbomb/archive/2005/03/24/329123.aspx
      4、手機(jī)性能問(wèn)題。
      不同手機(jī)的可用內(nèi)存、最大jar文件都有要求,例如Nokia S40的大部分手機(jī)支持的最大jar文件為64K,最大可用內(nèi)容為210K。
      所以現(xiàn)在的手機(jī)軟件,特別是游戲都提供支持的機(jī)型列表,也才有了手機(jī)游戲移植人員的存在。

    四、學(xué)習(xí)J2ME可以從事的工作種類
      現(xiàn)在J2ME技術(shù)可以說(shuō)相當(dāng)?shù)幕鸨@里介紹一些學(xué)好了J2ME之后可以從事的工作的種類:
      1、J2ME游戲開發(fā)人員
      根據(jù)游戲策劃或者文檔要求,在某種特定的機(jī)型(以Nokia S40或S60居多)開發(fā)游戲程序。
      這是現(xiàn)在大部分J2ME程序員從事的工作。
      需要熟練掌握:高級(jí)用戶界面、低級(jí)用戶界面、線程,如果是網(wǎng)絡(luò)游戲,還需要熟練網(wǎng)絡(luò)編程。
      2、J2ME應(yīng)用開發(fā)人員
      現(xiàn)在的移動(dòng)應(yīng)用還不是很多,但是還是出現(xiàn)了一些,特別是移動(dòng)定位以及移動(dòng)商務(wù)相關(guān)的內(nèi)容。
      需要熟練掌握:高級(jí)用戶界面、線程和網(wǎng)絡(luò)編程。
      3、J2ME游戲移植人員
      參照源代碼,將可以在一個(gè)平臺(tái)上可以運(yùn)行的游戲移植到其他平臺(tái)上去。例如將Nokia S40的游戲移植到S60上,或者索愛的T618等等。
      主要是控制屏幕坐標(biāo),有些可能需要替換一些API。
      需要熟悉各平臺(tái)之間的差異以及相關(guān)的技術(shù)參數(shù),比如屏幕大小、最大jar文件尺寸等等。

    五、J2ME程序設(shè)計(jì)的幾個(gè)原則
      1、使用面向?qū)ο缶幊獭?BR>  雖然使用面向過(guò)程編程可以減小文件的尺寸,但是為了以后維護(hù)的方便和利于擴(kuò)展,還是要使用面向?qū)ο缶幊獭?BR>  2、使用MVC模式
      將模型、界面和控制分離。現(xiàn)在很多的程序?qū)⑷吆弦唬侨绻阕龅某绦虮容^大的話,還是建議你進(jìn)行分離。
      3、自動(dòng)存儲(chǔ)用戶設(shè)定
      使用RMS來(lái)存儲(chǔ)用戶的信息,例如存儲(chǔ)用戶上次輸入的用戶名、密碼、用戶對(duì)于系統(tǒng)的設(shè)定等,這樣不僅可以減少用戶的輸入,而且對(duì)用戶友好。很多程序甚至做了自動(dòng)登陸等。
      4、一些系統(tǒng)設(shè)置允許用戶關(guān)閉。如背景音樂、背景燈顯示等。
      5、將低級(jí)用戶界面的繪制動(dòng)作放在一個(gè)獨(dú)立的線程里面去。
      6、在需要大量時(shí)間才能完成的工作時(shí),給用戶一個(gè)等待界面。

    六、從模擬器到真機(jī)測(cè)試
      對(duì)于J2ME開發(fā)者來(lái)說(shuō),模擬器給我們帶來(lái)了很多方便,比如可以在模擬器中調(diào)試程序以及很方便的察看程序的效果,但是模擬器也給我們帶來(lái)了一些問(wèn)題,比如模擬器實(shí)現(xiàn)的bug等等,所以進(jìn)行真機(jī)測(cè)試是必須的。
      1、為什么要進(jìn)行真機(jī)測(cè)試?
      因?yàn)槟M器程序可能存在bug,以及真機(jī)的性能有限,所以必須進(jìn)行真機(jī)測(cè)試。
      2、如何將程序傳輸?shù)綑C(jī)器中?
      將程序傳輸?shù)綑C(jī)器中有如下方式:
        a) OTA下載
        b) 使用數(shù)據(jù)線傳輸
        c) 紅外傳輸
        d) 藍(lán)牙
      你可以根據(jù)條件,選擇合適的方式。
      3、 真機(jī)測(cè)試主要測(cè)什么?
      真機(jī)測(cè)試的內(nèi)容很多,主要測(cè)試以下幾個(gè)方面:
        a) 程序的功能
        b) 程序的操作性,是否易操作
        c) 程序的大小,比如Nokia S40系列的手機(jī)大部分接受的最大文件尺寸為64K
        d) 程序運(yùn)行速度,速度是否可以忍受。

    七、從WTK到廠商SDK
      對(duì)于J2ME愛好者來(lái)說(shuō),基本上大家都是從SUN的WTK(J2ME Wireless Toolkit)開始的,但是對(duì)于實(shí)際應(yīng)用來(lái)說(shuō),僅僅使用WTK是遠(yuǎn)遠(yuǎn)不夠的,所以在學(xué)習(xí)過(guò)程中,必須完成從WTK到SDK的跨越。
      1、廠商SDK的下載地址?
      http://blog.csdn.net/Mailbomb/archive/2005/01/01/236606.aspx
      2、廠商SDK和WTK有什么不同?
      廠商SDK最簡(jiǎn)單的理解就是在WTK的基礎(chǔ)上增加了自己的模擬器和自己的擴(kuò)展API。
      也就是說(shuō),你在使用廠商的SDK時(shí),可以使用廠商的擴(kuò)展類庫(kù),例如Nokia的UI類庫(kù),和廠商自己的模擬器而已。
      每個(gè)廠商的擴(kuò)展API都不多,而且不盡相同。
      3、如何使用?
      有些廠商SDK的使用都和WTK相同,例如SamSung。
      Nokia提供了獨(dú)立的界面來(lái)開發(fā),但是這個(gè)界面在實(shí)際開發(fā)中使用不多。
      4、廠商SDK的問(wèn)題
      廠商SDK實(shí)現(xiàn)過(guò)程中,有一些bug,而且和真機(jī)實(shí)現(xiàn)不一致。例如NOKIA的混音播放問(wèn)題等等。

    八、在J2ME中獲得手機(jī)IMEI的方法
      IMEI是Internation mobile entity identification的簡(jiǎn)稱,在手機(jī)中輸入*#06#可以顯示該數(shù)字,長(zhǎng)度為15位,全球唯一,永遠(yuǎn)不會(huì)沖突,所以可以作為識(shí)別用戶的一個(gè)標(biāo)志。
      下面是在J2ME中獲得IMEI的方法:
      1、MOTO系列的手機(jī)可以通過(guò)讀取系統(tǒng)的IMEI屬性獲得,代碼如下:
                 String imei = System.getProperty("IMEI");
      2、SIEMENS系列的手機(jī)可以通過(guò)讀取系統(tǒng)的com.siemens.IMEI屬性獲得,代碼如下:
                 String imei = System.getProperty("com.siemens.IMEI");

    九、J2ME網(wǎng)絡(luò)連接中顯示問(wèn)題的解決辦法
      在網(wǎng)絡(luò)編程中,有些時(shí)候會(huì)出現(xiàn)一些在沒有接收到網(wǎng)絡(luò)數(shù)據(jù)就顯示界面的,造成界面顯示不符合要求(例如公告顯示,會(huì)先顯示公告的背景圖片再顯示公告信息),這里提一個(gè)簡(jiǎn)單的解決辦法給大家:
      解決這種情況的方法分成三個(gè)步驟:
      1、在需要顯示的界面中,調(diào)用發(fā)送網(wǎng)絡(luò)數(shù)據(jù)的方法。每次顯示時(shí)調(diào)用該構(gòu)造方法,不調(diào)用Display的setCurrent方法顯示。
      2、顯示等待界面(例如進(jìn)度條等),給用戶提示,在進(jìn)行網(wǎng)絡(luò)連接。
      3、在處理網(wǎng)絡(luò)反饋的數(shù)據(jù)完以后,調(diào)用Display的setCurrent方法顯示顯示當(dāng)前界面。

    十、增強(qiáng)J2ME的String能力——分割字符串
      從JDK1.4以后,String類中新增了split方法來(lái)實(shí)現(xiàn)字符串的分割,但是在J2ME中卻沒有該方法(MIDP2.0中也沒有實(shí)現(xiàn)),但是在實(shí)際使用過(guò)程中,有些時(shí)候的確要用到這種操作,這里將我以前實(shí)現(xiàn)的一段代碼和大家共享:
    /**
    * 分割字符串,原理:檢測(cè)字符串中的分割字符串,然后取子串
    * @param original 需要分割的字符串
    * @paran regex 分割字符串
    * @return 分割后生成的字符串?dāng)?shù)組
    */

    private static String[] split(String original,String regex)
    {
         //取子串的起始位置
         int startIndex = 0;
         //將結(jié)果數(shù)據(jù)先放入Vector中
         Vector v = new Vector();
         //返回的結(jié)果字符串?dāng)?shù)組
         String[] str = null;
         //存儲(chǔ)取子串時(shí)起始位置
         int index = 0;

         //獲得匹配子串的位置
         startIndex = original.indexOf(regex);
         //System.out.println("0" + startIndex);
         //如果起始字符串的位置小于字符串的長(zhǎng)度,則證明沒有取到字符串末尾。
         //-1代表取到了末尾
         while(startIndex < original.length() && startIndex != -1)
         {
               String temp = original.substring(index,startIndex);
               System.out.println(" " + startIndex);
               //取子串
               v.addElement(temp);

               //設(shè)置取子串的起始位置
               index = startIndex + regex.length();

               //獲得匹配子串的位置
               startIndex = original.indexOf(regex,startIndex + regex.length());
         }

         //取結(jié)束的子串
         v.addElement(original.substring(index + 1 - regex.length()));
         //將Vector對(duì)象轉(zhuǎn)換成數(shù)組
         str = new String[v.size()];
         for(int i=0;i
         {
              str[i] = (String)v.elementAt(i);
         }
        
         //返回生成的數(shù)組
         return str;
    }

    十一、J2ME在低級(jí)用戶界面上分行顯示文字
      在J2ME的低級(jí)用戶界面開發(fā)中,經(jīng)常會(huì)遇到需要在Canvas上顯示大量的文字,例如關(guān)于界面、游戲說(shuō)明、游戲公告等信息。如果在設(shè)計(jì)時(shí),將文字的內(nèi)容和長(zhǎng)度都固定,既不利于修改也不利于維護(hù)。下面介紹一個(gè)簡(jiǎn)單的方法,實(shí)現(xiàn)一個(gè)簡(jiǎn)單、可維護(hù)性強(qiáng)的方式。
      實(shí)現(xiàn)方法:
        1、將需要顯示的所有信息做成一個(gè)字符串。
        2、編寫一個(gè)將該字符串按照要求轉(zhuǎn)換為字符串?dāng)?shù)組的方法。
        3、將轉(zhuǎn)換后的數(shù)組以循環(huán)的方式顯示在Canvas上。
      通過(guò)這樣三個(gè)步驟,則修改顯示的信息時(shí),只需要修改包含顯示信息的字符串即可,自己書寫的方法可以按照以前的標(biāo)準(zhǔn)重新分割新的字符串。如果需要修改每行顯示的字符個(gè)數(shù),則只需要修改自己書寫的方法即可。
      通過(guò)這樣一種實(shí)現(xiàn)方式,可以很方便的實(shí)現(xiàn)顯示一些比較長(zhǎng)的文本信息,即使是可變長(zhǎng)度的字符串也沒有問(wèn)題。

    十二、J2ME中使用記錄存儲(chǔ)系統(tǒng)(RMS)存儲(chǔ)信息
      在MIDP中,沒有文件的概念,所以永久存儲(chǔ)一般只能依靠記錄存儲(chǔ)系統(tǒng)實(shí)現(xiàn),關(guān)于記錄存儲(chǔ)系統(tǒng)的簡(jiǎn)介,可以參看教程:http://www-900.ibm.com/developerWorks/cn/java/j-wi-rms/index.shtml
      下面是一些記錄存儲(chǔ)系統(tǒng)的常用編碼介紹:
        1、打開記錄集:
      打開記錄集使用RecordStore里面的靜態(tài)方法openRecordStore,示例代碼如下:
              RecordStore rs = RecordStore.openRecordStore(“username”,true);
      這樣就打開了一個(gè)名稱為rs的記錄集,其中username為記錄集的名稱,該名稱可以根據(jù)需要來(lái)取,第二個(gè)參數(shù)代表是否則沒有時(shí)創(chuàng)建新的記錄集,true代表在該記錄集不存在時(shí),創(chuàng)建新的記錄集,false代表不創(chuàng)建。
      如果在打開記錄集時(shí),該記錄集不存在,則拋出RecordStoreNotFoundException異常,所以檢測(cè)記錄集是否已創(chuàng)建可以使用該異常。
      注意:記錄集打開以后記得關(guān)閉。
        2、向記錄集中寫入數(shù)據(jù)
            2.1增加數(shù)據(jù)
      向已經(jīng)打開的記錄集中添加數(shù)據(jù),需要使用addRecord方法,示例代碼:
                     byte[] bytes = {1,2,3};
                 int id = rs. addRecord(bytes,0,bytes.length);
      該代碼將字節(jié)數(shù)組bytes的全部?jī)?nèi)容寫入到記錄集中,該方法的返回值為該信息的id,注意:id從1開始,而不是從0開始。
      你可以循環(huán)使用該方法向記錄集中寫入多條數(shù)據(jù)。
            2.2修改數(shù)據(jù)
      修改已經(jīng)存在的記錄集中指定id的數(shù)據(jù),需要使用setRecord方法,示例代碼:
                     byte[] bytes = {1,2,3};
                 rs. setRecord(1,bytes,0,bytes.length);
      以上代碼的作用是將字節(jié)數(shù)組bytes的全部?jī)?nèi)容寫入到id為1的記錄集rs中。
      該操作會(huì)覆蓋已有的數(shù)據(jù)。
      說(shuō)明:有些時(shí)候,你需要將信息寫入到記錄集中的第一條記錄中,則可以結(jié)合以上兩個(gè)方法,則第一次時(shí)向記錄集增加數(shù)據(jù),以后來(lái)進(jìn)行修改。
        3、從記錄集中讀出數(shù)據(jù)
      從記錄集中讀取已有數(shù)據(jù),需要使用getRecord方法,示例代碼:
                byte[] bytes = rs. getRecord(1);
      該代碼從記錄集rs中讀取第一條數(shù)據(jù),將讀取到的數(shù)據(jù)放在bytes數(shù)組中。
      在讀取數(shù)據(jù)時(shí),可以獲得記錄集中id的個(gè)數(shù),可以使用getNumRecords方法獲得
      綜合代碼為:
           int number = rs. getNumRecords();
           int id = 1;
           if(id >0 && id < number)
           {
           byte[] bytes = rs. getRecord(1);
           }
        4、從記錄集中刪除記錄
      從記錄集中刪除記錄的方法有兩種:邏輯刪除和物理刪除。
      邏輯刪除是指給刪除的記錄打標(biāo)記。
      物理刪除是指從物理上刪除該記錄,但是該記錄的id不能被重用,也就是說(shuō)該id不會(huì)被繼續(xù)使用。例如一個(gè)記錄集中有5個(gè)記錄,假設(shè)你刪除了id為3的數(shù)據(jù),則剩余記錄的id依然為1、2、4、5。這給便歷帶來(lái)了一定的麻煩。
        5、便歷記錄集
      便歷記錄集,即訪問(wèn)記錄集中的所有數(shù)據(jù),有兩個(gè)方法,詳見:
    http://gceclub.sun.com.cn/NASApp/sme/controller/teclist?tid=0103
        6、其他操作
      刪除記錄集
      刪除記錄集不同于刪除記錄,需要使用deleteRecordStore方法,示例代碼:          
                    RecordStore. deleteRecordStore(“username”);
      該代碼刪除名稱為username的記錄集。

    十三、J2ME加密數(shù)據(jù)的一個(gè)第三方開源免費(fèi)類庫(kù)介紹
      在J2ME編程中,經(jīng)常遇到一些數(shù)據(jù)在存儲(chǔ)或者傳輸時(shí)需要加密,下面介紹一個(gè)第三方的加密類庫(kù)的一些資料:
      加密類庫(kù)的官方主頁(yè):http://www.bouncycastle.org/
      介紹的文章:
      中文:http://18900.motorola.com/ewa_portal/develope/jc_j2messl_5_1.jsp
      英文:http://www.javaworld.com/javaworld/jw-12-2002/jw-1220-wireless.html
      該文章的源代碼包含使用的一些方法。
      備注:因?yàn)樵擃悗?kù)提供的功能比較強(qiáng)大,所以類庫(kù)的尺寸比較大,最后在發(fā)布時(shí)需要將類庫(kù)中不需要的類刪除

    十四、如何播放聲音
      在J2ME中,處理聲音需要使用到Mobile Media API(MMAPI),該包是MIDP1.0的可選包,在MIDP2.0中已經(jīng)包含了這個(gè)包。所以如果你使用MIDP1.0的話,請(qǐng)確認(rèn)你的運(yùn)行環(huán)境是否支持。
      一般手機(jī)支持的聲音文件格式為wav、mid和mpg等。具體請(qǐng)查閱你的手機(jī)說(shuō)明文檔。
      在聲音處理中,有很多處理的方式,這里說(shuō)一下最常用的情況,播放JAR文件中的wav文件。
      播放聲音文件的流程:
        1、按照一定的格式讀取聲音文件。
      播放JAR文件中的聲音文件一般是將聲音文件處理成流的形式。示例代碼:
                 InputStream is = this.getClass().getResourceAsStream("/Autorun.wav");
           其中Autorun.wav文件位于JAR文件的根目錄下,如果位于別的目錄,需要加上目錄名稱,如/res /Autorun.wav。
        2、將讀取到的內(nèi)容傳遞給播放器。
      將流信息傳遞給播放器,播放器按照一定的格式來(lái)進(jìn)行解碼操作,示例代碼:
                 Player player = Manager.createPlayer(is,"audio/x-wav");
      其中第一個(gè)參數(shù)為流對(duì)象,第二個(gè)參數(shù)為聲音文件的格式。
        3、播放聲音。
      使用Player對(duì)象的start方法,可以將聲音播放出來(lái),示例代碼:
                 player.start();
      在播放聲音時(shí)也可以設(shè)定聲音播放的次數(shù),可以使用Player類中的setLoopCount方法來(lái)實(shí)現(xiàn),具體可查閱API文檔。
      下面是在NOKIA S60模擬器中測(cè)試通過(guò)。代碼如下:
    package sound;
    import javax.microedition.midlet.*;
    import javax.microedition.lcdui.*;
    import javax.microedition.media.*;
    import java.io.*;

    public class SoundMIDlet extends MIDlet
    {
      private Player player = null;
      /** Constructor */
      public SoundMIDlet()
           {
                 try
                 {
                       InputStream is = this.getClass().getResourceAsStream("/Autorun.wav");
                       player = Manager.createPlayer(is,"audio/x-wav");
                 }
                 catch(IOException e)
                 {
                       System.out.println("1:" + e);
                 }
                 catch(MediaException e)
                 {
                       System.out.println("2:" + e);
                 }
                 catch(Exception e)
                 {
                       System.out.println("3:" + e);
                 }
          }

          /** Main method */
          public void startApp()
          {
                 if(player != null)
                 {
                       try
                       {
                  player.start();
                       }
                       catch(MediaException e)
                       {
                  System.out.println("4:" + e);
                       }
                 }
           }

           /** Handle pausing the MIDlet */
           public void pauseApp()
           {
           }

           /** Handle destroying the MIDlet */
           public void destroyApp(boolean unconditional)
           {
           }
    }

    十五、J2ME 3D編程的一些資料
      隨著J2ME技術(shù)的發(fā)展,以及硬件速度的提升,3D游戲程序?qū)⒙淖兂芍髁鳎罱雽W(xué)習(xí)這一塊的編程,所以收集了一些資料,和大家一起分享:
      1、JSR184
      JSR184是Nokia公司起草的一個(gè)關(guān)于3D API的規(guī)范,下載地址為:
      http://www.forum.nokia.com/main/1,,1_0_10,00.html#jsr184
      2、Nokia的3D編程資料
      http://www.forum.nokia.com/main/1,6566,21,00.html
      3、3D引擎
      一個(gè)簡(jiǎn)單的開放源代碼的3D游戲引擎
      http://www.j2me.com.cn/Soft_Show.asp?SoftID=19
      國(guó)內(nèi)一個(gè)合作開發(fā)3D引擎的項(xiàng)目:
      http://gceclub.sun.com.cn/NASApp/sme/jive/thread.jsp?forum=11&thread=8593
      4、一款3D游戲產(chǎn)品
      http://games.sina.com.cn/newgames/2004/04/040217696.shtml
      5、支持3D的開發(fā)工具
      當(dāng)前一些高端的手機(jī)支持3D開發(fā),支持3D開發(fā)的開發(fā)工具中,通用的有SUN的J2MEWTK2.2。專用的是廠商提高的支持JSR184的SDK。

    十六、3D編程——第一個(gè)3D程序
      參考WTK2.2提供的demo,完成了第一個(gè)3D程序,雖然很簡(jiǎn)單,而且有些問(wèn)題還不是很清楚,還是把代碼共享出來(lái)和愿意學(xué)習(xí)J2ME 3D編程的朋友一起學(xué)習(xí)。
      關(guān)于代碼的編譯和運(yùn)行說(shuō)明如下:
      1、以下代碼在J2ME WTK2.2下面編譯通過(guò)。
      2、代碼分為兩個(gè)文件:First3DCanvas.java和First3DMIDlet.java。
      3、使用J2ME WTK2.2建立新的工程,主MIDlet類為:first3d. First3DMIDlet
      4、將代碼保存在你的工程目錄下的first3d目錄下。
      5、將J2ME WTK安裝目錄下的apps\Demo3D\res\com\superscape\m3g\wtksamples\retainedmode\content目錄中的swerve.m3g文件復(fù)制到你的工程目錄下的res目錄下。
      6、你的工程建立后,設(shè)置工程,通過(guò)WTK界面中的“設(shè)置”按鈕打開設(shè)置窗口,在“API選擇”中,設(shè)置“目標(biāo)平臺(tái)”為:自定義;“簡(jiǎn)檔”為“MIDP2.0”;“配置”為“CLDC1.1”;選中“Mobile 3D Graphics for J2ME(JSR184)”。
      7、這樣你就可以編譯和運(yùn)行以下代碼了。
      源代碼如下:

    // First3DMIDlet.java
    package first3d;
    import javax.microedition.midlet.*;
    import javax.microedition.lcdui.*;
    public class First3DMIDlet extends MIDlet
    {
          private First3DCanvas displayable = new First3DCanvas();
          public void startApp()
          {
                Display.getDisplay(this).setCurrent(displayable);
          }

          public void pauseApp() {}

          public void destroyApp(boolean unconditional) {}
    }

    // First3Dcanvas.java
    package first3d;
    import javax.microedition.lcdui.*;
    import javax.microedition.m3g.*;
    import java.util.*;
    /**
    * 第一個(gè)3D程序
    */
    public class First3DCanvas extends Canvas implements Runnable
    {
          /**World對(duì)象*/
          private World myWorld = null;
          /**Graphics3D對(duì)象*/
          private Graphics3D g3d = Graphics3D.getInstance();
          /**Camera對(duì)象*/
          private Camera cam = null;
          private int viewport_x;
          private int viewport_y;
          private int viewport_width;
          private int viewport_height;
          private long worldStartTime = 0;
          //重繪時(shí)間
          private int validity = 0;
         
          public First3DCanvas()
          {
                //啟動(dòng)重繪界面的線程
                Thread thread = new Thread(this);
                thread.start();
                try
                {
                       //導(dǎo)入3D圖片
                       myWorld = (World) Loader.load("/swerve.m3g")[0];
                       viewport_x = 0;
                       viewport_y = 0;
                       viewport_width = getWidth();
                       viewport_height = getHeight();
                       cam = myWorld.getActiveCamera();
                       //設(shè)置cam對(duì)象
                       float[] params = new float[4];
                       int type = cam.getProjection(params);
                       if (type != Camera.GENERIC)
                       {
                              //calculate window aspect ratio
                              float waspect = viewport_width / viewport_height;
                              if (waspect < params[1])
                              {
                                    float height = viewport_width / params[1];
                                    viewport_height = (int) height;
                                    viewport_y = (getHeight() - viewport_height) / 2;
                              }
                              else
                              {
                                    float width = viewport_height * params[1];
                                    viewport_width = (int) width;
                                    viewport_x = (getWidth() - viewport_width) / 2;
                              }
                       }
                       worldStartTime = System.currentTimeMillis();
                }
                catch (Exception e) {}
          }
         
          protected void paint(Graphics g)
          {
                //清除背景
                g.setColor(0x00);
                g.fillRect(0, 0, getWidth(), getHeight());
                //和3D對(duì)象綁定
                g3d.bindTarget(g);
                g3d.setViewport(viewport_x, viewport_y, viewport_width, viewport_height);
                long startTime = System.currentTimeMillis() - worldStartTime;
                validity = myWorld.animate((int)startTime);
                try
                {
                       g3d.render(myWorld);
                }
                finally
                {
                       g3d.releaseTarget();
                }
          }

          public void run()
          {
                try
                {
                       while(true)
                       {
                             //重繪圖形
                             repaint(viewport_x, viewport_y, viewport_width, viewport_height);
                       }
                }
                catch(Exception e){}
          }
    }

    十七、在J2ME網(wǎng)絡(luò)編程中使用CMWAP代理
      在中國(guó)移動(dòng)提供的網(wǎng)絡(luò)連接中,分為CMNET和CMWAP兩種,其中CMNET可以無(wú)限制的訪問(wèn)互聯(lián)網(wǎng)絡(luò),資費(fèi)比較貴。CMWAP類似一個(gè)HTTP的代碼,只能訪問(wèn)支持HTTP的應(yīng)用,但是資費(fèi)便宜,穩(wěn)定性比較差。
      在實(shí)際的J2ME網(wǎng)絡(luò)編程中,一般需要提供以CMWAP代理的方式連接網(wǎng)絡(luò),在J2ME中,連接的代碼和直接連接有所不同,代碼如下:
                 HttpConnection http = (HttpConnection)Connector.open((");
                 http.setRequestProperty("X-Online-Host",ServerName);
      例如你需要訪問(wèn)的地址為:
    http://www.test.com/login/loginServlet則上面的代碼就為:
                 HttpConnection http = (HttpConnection)Connector.open(("             http.setRequestProperty("X-Online-Host","  在實(shí)際使用過(guò)程中,只需要使用實(shí)際需要訪問(wèn)的地址的域名或者IP來(lái)代替ServerName,例如示例中的“www.test.com”,使用后續(xù)的地址類代替代碼中的url,例如示例中的“l(fā)ogin/loginServlet”,就可以實(shí)際的使用CMWAP代理來(lái)進(jìn)行連接了。

    十八、J2ME中的時(shí)間處理全攻略
      時(shí)間處理在程序開發(fā)中相當(dāng)常見,下面對(duì)于時(shí)間處理做一個(gè)簡(jiǎn)單的說(shuō)明。
      一、時(shí)間的表達(dá)方式
      時(shí)間在J2ME中有兩種表達(dá)方式:
      1、以和GMT1970年1月1號(hào)午夜12點(diǎn)和現(xiàn)在相差的毫秒數(shù)來(lái)代表
      這種方式適合比較兩個(gè)時(shí)間之間的差值。
      2、以對(duì)象的形式來(lái)表達(dá)
      二、時(shí)間處理的相關(guān)類
      時(shí)間處理在J2ME中涉及三個(gè)類:
      1、System類
       long time = System. currentTimeMillis();
      使用該方法可以獲得當(dāng)前時(shí)間,時(shí)間的表達(dá)方式為上面提到的第一種。
      2、Date類
       Date date = new Date();
      獲得當(dāng)前時(shí)間,使用對(duì)象的形式來(lái)進(jìn)行表達(dá)。
      3、Calendar類
       Calendar calendar = Calendar. getInstance();

    三、時(shí)間處理的具體操作
      1、以上三種表達(dá)方式的轉(zhuǎn)換:
      a)將System類獲得的時(shí)間轉(zhuǎn)換為Date對(duì)象
       Date date = new Date(System. currentTimeMillis());
      b)將Date類型的對(duì)象轉(zhuǎn)換為Calendar類型的對(duì)象
       Calendar calendar = Calendar. getInstance();
       Date date = new Date();
       calendar.setTime(date);
      2、使用Calendar完成一些日期操作:
      Calendar是時(shí)間處理中最常用也是功能最強(qiáng)大的類,可以用它來(lái)獲得某個(gè)時(shí)間的日期、星期幾等信息。
      獲得日期:
       Calendar calendar = Calendar. getInstance();
       ……
       int day = calendar.get(Calendar. DATE);
      獲得日期、年份、星期的操作和這個(gè)類似。
      需要注意的是:Calendar中表示月份的數(shù)字和實(shí)際相差1,即1月用數(shù)字0表示,2月用數(shù)字1表示,……12月用數(shù)字11表示。

    十九、J2ME中隨機(jī)數(shù)字處理全攻略
      在程序中生成隨機(jī)數(shù)字,用處比較,如人工智能領(lǐng)域等等,這里對(duì)于在J2ME中生成隨機(jī)數(shù)的操作進(jìn)行一個(gè)簡(jiǎn)單的整理,希望對(duì)大家能有幫助。
      J2ME和J2SE不同,不能使用Math類的random來(lái)生成隨機(jī)數(shù)字,只能使用java.util包的Random類來(lái)生成隨機(jī)數(shù)字。
      1、創(chuàng)建Random類型的對(duì)象:
             Random random = new Random();
       Random random = new Random(10010010);
      以上兩種是創(chuàng)建Random對(duì)象的方式,第一種使用默認(rèn)構(gòu)造方法,和以下的代碼作用完全等價(jià):
       Random random = new Random(System. currentTimeMillis());
      相當(dāng)與使用當(dāng)前時(shí)間作為種子數(shù)字來(lái)進(jìn)行創(chuàng)建。
      第二種方式通過(guò)自己來(lái)指定種子數(shù)字來(lái)進(jìn)行創(chuàng)建。
      大家可以根據(jù)需要使用以上兩種方式的任一種。
      2、生成隨機(jī)數(shù)字:
      創(chuàng)建好了隨機(jī)對(duì)象以后,我們就可以來(lái)生成隨機(jī)數(shù)字了:
      生成隨機(jī)整數(shù):
             int k = random.nextInt();
           生成隨機(jī)長(zhǎng)整數(shù):
             long l = random.nextLong();
      3、生成指定范圍的數(shù)字:
      例如生成0-10之間的隨機(jī)數(shù)字:
             int k = random.nextInt();
       int j = Math.abs(k % 10);
      首先生成一個(gè)隨機(jī)整數(shù)k,然后用k和10取余,最后使用Math類的abs方法取絕對(duì)值,獲得0-10之間的隨機(jī)數(shù)字。
      獲得0-15之間的隨機(jī)數(shù),類似:
             int k = random.nextInt();
       int j = Math.abs(k % 15);
      獲得10-20之間的隨機(jī)數(shù)字:
             int k = random.nextInt();
       int j = Math.abs(k % 10) + 10;

    二十、在J2ME手機(jī)編程中使用字體
      在J2ME手機(jī)編程中,可以通過(guò)使用字體類——Font在低級(jí)用戶界面中,獲得更好的表現(xiàn)效果,那么如何使用Font類呢?
      首先,由于手機(jī)設(shè)備的限制,手機(jī)中支持的字體類型很有限,所以在J2ME中只能使用手機(jī)支持的默認(rèn)字體來(lái)構(gòu)造Font類對(duì)象。下面是創(chuàng)建Font類的對(duì)象時(shí)使用的方法:
              getFont(int face,int style,int size);
    例如:
              Font font = Font.getFont(Font.FACE_SYSTEM,Font.STYLE_BOLD,Font. SIZE_MEDIUM);
      無(wú)論哪一個(gè)參數(shù),都只能使用系統(tǒng)設(shè)置的數(shù)值,這些數(shù)值具體的大小在不同的手機(jī)上可能不同。下面對(duì)于其中的三個(gè)參數(shù)的取值做詳細(xì)的介紹:
      face參數(shù)指字體的外觀,其的取值:
      FACE_MONOSPACE——等寬字體
      FACE_PROPORTIONAL——均衡字體
      FACE_SYSTEM——系統(tǒng)字體
      style參數(shù)指字體的樣式,其的取值:
      STYLE_BOLD——粗體
      STYLE_ITALIC——斜體
      STYLE_PLAIN——普通
      STYLE_UNDERLINED——下劃線
      STYLE_BOLD | STYLE_ITALIC——粗斜體
      STYLE_UNDERLINED | STYLE_BOLD——帶下劃線粗體
      STYLE_UNDERLINED | STYLE_ITALIC——帶下劃線斜體
      STYLE_UNDERLINED | STYLE_ITALIC | STYLE_BOLD——帶下劃線的粗斜體
      size參數(shù)指字體的大小,其的取值:
      SIZE_SMALL——小
      SIZE_MEDIUM——中
      SIZE_LARGE——大
      通過(guò)上面的參數(shù)的值,可以組合出你需要的字體對(duì)象。
      下面是一些常用的字體操作:
      1. 獲得系統(tǒng)的默認(rèn)字體:
              Font font = Font.getDefaultFont();
      2. 在panit方法內(nèi)部,假設(shè)Graphics參數(shù)的名稱為g,則獲得當(dāng)前字體的方法是:
              Font font = g.getFont();
      3. 在panit方法內(nèi)部,假設(shè)Graphics參數(shù)的名稱為g,則設(shè)置當(dāng)前字體的方法是:
              g.setFont(font);
      其中font為你構(gòu)造好的字體對(duì)象。
      4. 在MIDP2.0中,List可以設(shè)置每行的字體格式,方法是:
              list.setFont(0,font);
      則上面的代碼是將list中的第一行設(shè)置為font類型的字體。

    二十一、在J2ME手機(jī)程序開發(fā)中使用顏色
      在J2ME手機(jī)開發(fā)過(guò)程中,需要經(jīng)常用到顏色來(lái)進(jìn)行繪制,增強(qiáng)程序的表現(xiàn)效果,下面就介紹一下如何使用顏色。
      由于J2ME技術(shù)比較簡(jiǎn)單,所以沒有實(shí)現(xiàn)專門的顏色類,而只是使用RGB的概念來(lái)代表顏色。這里簡(jiǎn)單介紹一下RGB的概念,顏色是由紅(Red)、綠(Green)、藍(lán)(Blue)三原色組成的,所以可以使用這三個(gè)顏色的組合來(lái)代表一種具體的顏色,其中R、G、B的每個(gè)數(shù)值都位于0-255之間。在表達(dá)顏色的時(shí)候,即可以使用三個(gè)數(shù)字來(lái)表達(dá),也可以使用一個(gè)格式如0X00RRGGBB這樣格式的十六進(jìn)制來(lái)表達(dá),下面是常見顏色的表達(dá)形式:
      紅色:(255,0,0)或0x00FF0000
      綠色:(0,255,0)或0x0000FF00
      藍(lán)色:(255,255,255)或0x00FFFFFF
      其他顏色也可以通過(guò)上面的方式組合出來(lái)。
      知道了顏色的表達(dá)方式以后,下面來(lái)介紹一下如何在J2ME程序中使用顏色,涉及的方法均在Graphics類中,有以下幾個(gè):
      1.getColor():
      獲得當(dāng)前使用的顏色,返回值是0x00RRGGBB格式的數(shù)字。例如:
              int color = g.getColor();
      其中g(shù)為Graphics類型的對(duì)象。
      2.setColor(int RGB):
      設(shè)置使用的顏色。例如:
              g.setColor(0x00ff0000);
      3.setColor(int red, int green, int blue)
      和上面的方法作用一樣,例如:
              g.setColor(255,0,0);
      在設(shè)置了Graphics使用的顏色以后,再進(jìn)行繪制的時(shí)候,就可以繪制指定的顏色了。

    二十二、在J2ME聯(lián)網(wǎng)應(yīng)用中獲得客戶端的手機(jī)號(hào)碼
      在J2ME程序開發(fā)過(guò)程中,為了一定的需要,經(jīng)常需要來(lái)獲得用戶的手機(jī)號(hào)碼,但是這個(gè)功能卻在標(biāo)準(zhǔn)的J2ME類庫(kù)中沒有提供。
      在使用中國(guó)移動(dòng)的CMWAP方式連接網(wǎng)絡(luò)時(shí),中國(guó)移動(dòng)會(huì)將用戶的手機(jī)號(hào)碼放在一個(gè)名稱為x-up-calling-line-id的頭信息中,可以通過(guò)讀取該頭信息,獲得用戶的手機(jī)號(hào)碼,具體代碼如下:
              String usermphone = http.getHeader("x-up-calling-line-id");
      其中http是HttpConnction類型的對(duì)象。

    二十三、使用J2ME發(fā)送手機(jī)短信息
      在程序中,發(fā)送短信息的方式一般有三種:
      1、 使用程序在網(wǎng)絡(luò)上發(fā)送短信息,例如各大網(wǎng)站的短信業(yè)務(wù)。這種方式是通過(guò)程序?qū)⑿畔l(fā)送給運(yùn)營(yíng)商的網(wǎng)關(guān)服務(wù)器,然后通過(guò)運(yùn)營(yíng)商的網(wǎng)絡(luò)發(fā)送給手機(jī)。
      2、 在計(jì)算機(jī)中,通過(guò)數(shù)據(jù)線連接到手機(jī),然后通過(guò)手機(jī)來(lái)發(fā)送短信息。這種方式是通過(guò)使用AT指令來(lái)實(shí)現(xiàn)。愛立信手機(jī)的AT指令你可以在以下地址找到:
    http://mobilityworld.ericsson.com.cn/development/download_hit.asp
      3、 通過(guò)在手機(jī)中運(yùn)行的程序來(lái)發(fā)送短信息。這個(gè)正是本文實(shí)現(xiàn)的方式。
      在J2ME中,如果想發(fā)送短信息,需要使用WMA包,MIDP2.0中已經(jīng)包含,MIDP1.0中可以通過(guò)廠商提供的擴(kuò)展API實(shí)現(xiàn),和WMA的類庫(kù)基本一樣。
           下面是使用WMA向指定手機(jī)號(hào)碼發(fā)送短信息的一個(gè)方法,很簡(jiǎn)單。當(dāng)然WMA也提供了其他的方式來(lái)發(fā)送更多的內(nèi)容。

    // SMSUtil.java
    package my.util;
    import javax.wireless.messaging.*;
    import javax.microedition.io.*;
    /**
    * 發(fā)送文本短信息的方法
    */
    public class SMSUtil
    {
          /**
          * 給指定號(hào)碼發(fā)送短信息
          * @param content 短信息內(nèi)容
          * @param phoneNumber 手機(jī)號(hào)碼
          * @return 發(fā)送成功返回true,否則返回false
          */
          public static boolean send(String content,String phoneNumber)
          {
                //返回值
                boolean result = true;
                try
                {
                       //地址
                       String address = "sms://+" + phoneNumber;
                       //建立連接
                       MessageConnection conn = (MessageConnection)Connector.open(address);
                       //設(shè)置短信息類型為文本,短信息有文本和二進(jìn)制兩種類型
                       TextMessage msg = (TextMessage)conn.newMessage(MessageConnection.TEXT_MESSAGE);
                       //設(shè)置信息內(nèi)容
                       msg.setPayloadText(content);
                       //發(fā)送
                       conn.send(msg);
                }
                catch(Exception e)
                {
                       result = false;
                       //未處理
                }
                return result;
          }
    }

    二十四、使用簡(jiǎn)單的J2ME程序測(cè)試MIDlet的生命周期
      在MIDlet程序?qū)W習(xí)中,生命周期是一個(gè)比較抽象的概念。其實(shí)生命周期就是一個(gè)簡(jiǎn)單的規(guī)定,規(guī)定了MIDlet中的每個(gè)方法,什么時(shí)候被系統(tǒng)調(diào)用。下面是一個(gè)示例代碼,在每個(gè)方法的內(nèi)部都輸出一條語(yǔ)句,可以根據(jù)程序的輸出結(jié)果來(lái)驗(yàn)證各方法被調(diào)用的順序,具體代碼如下:


    //文件名:LifeCircleMIDlet.java
    import javax.microedition.midlet.*;
    /**
    * 測(cè)試MIDlet的生命周期
    */
    public class LifeCircleMIDlet extends MIDlet
    {
          /**
          * 默認(rèn)構(gòu)造方法
          */
          public LifeCircleMIDlet()
          {
                System.out.println("默認(rèn)構(gòu)造方法");
          }
          /**
          * 啟動(dòng)方法
          */
          public void startApp()
          {
                System.out.println("startApp方法");
          }
          /**
          * 暫停方法
          */
          public void pauseApp()
          {
                System.out.println("pauseApp方法");
          }
          /**
          * 銷毀方法
          * @param b
          */
          public void destroyApp(boolean b)
          {
                System.out.println("destroyApp方法");
          }
    }
      在J2WTK中運(yùn)行該程序時(shí),可以使用瀏覽器中的“MIDlet”菜單中的暫停和恢復(fù)菜單,模擬暫停事件。

    二十五、使用OTA來(lái)發(fā)布你的程序
      眾所周知,J2ME程序發(fā)布的形式主要有:OTA、數(shù)據(jù)線傳輸、紅外和藍(lán)牙傳輸?shù)取_@里簡(jiǎn)單說(shuō)說(shuō)如何通過(guò)OTA來(lái)發(fā)布你的程序。
      OTA是Over The Air的簡(jiǎn)寫,也就是通過(guò)網(wǎng)絡(luò)下載,這是主要的發(fā)布形式之一。現(xiàn)在的百寶箱都是采用這種形式。
      使用OTA來(lái)發(fā)布程序,需要如下幾個(gè)步驟:
      1、在你的WEB服務(wù)器上添加對(duì)于jad和jar文件的MIME支持。
      后綴名:jad
      MIME類型:text/vnd.sun.j2me.app-descriptor
      后綴名:jar
      MIME類型:application/java-archive
      2、發(fā)布WML頁(yè)面:
      例如你的jar文件名test.jad,則最簡(jiǎn)單的下載頁(yè)面是:
      <?xml version="1.0"?>
      <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.3//EN"
      "  <wml>
      <card id="card1" title="Download Midlet">
      <a href="test.jad">test</a>
      </card>
      </wml>
      你可以將以上代碼保存在WEB服務(wù)器上,例如保存為text.wml
      3、修改jad文件:
      在jad文件中增加 MIDlet-Jar-URL:
    http://domain/directory/test.jar
      其中的http://domain/directory/test.jar為你的jar文件的路徑。
      經(jīng)過(guò)上面的設(shè)置,你就可以將你的wml頁(yè)面路徑作為你的WAP下載頁(yè)面發(fā)布了。用戶只需要在手機(jī)上輸入這個(gè)路徑就可以訪問(wèn)和下載你的程序了。


    posted on 2005-11-18 09:21 Steve 閱讀(364) 評(píng)論(0)  編輯  收藏

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲中文字幕无码专区| 亚洲电影免费观看| 精品久久久久久国产免费了| 在线观看亚洲网站| 亚洲av无码偷拍在线观看| 中文字幕亚洲综合久久综合| 久久国产亚洲精品| 亚洲爆乳成av人在线视菜奈实| 亚洲中文字幕久久精品无码A| 亚洲熟女综合一区二区三区| 亚洲欧美国产精品专区久久| 亚洲AV成人无码久久WWW| 边摸边吃奶边做爽免费视频网站| 免费很黄无遮挡的视频毛片| caoporm碰最新免费公开视频| av永久免费网站在线观看| 四虎国产精品永久免费网址 | 亚洲精品中文字幕麻豆| 亚洲另类古典武侠| 亚洲精品国产高清在线观看| 狼人大香伊蕉国产WWW亚洲| 日韩精品免费一线在线观看| 久久嫩草影院免费看夜色| 日本免费人成视频在线观看| 免费黄色网址网站| 全免费a级毛片免费**视频| 亚洲成av人片一区二区三区| 亚洲大尺度无码无码专区| 亚洲精品在线免费观看| 亚洲另类无码专区丝袜| 一级做a毛片免费视频| 精品国产免费一区二区三区香蕉| 香蕉97超级碰碰碰免费公| 国产一区二区三区免费在线观看| 亚洲日韩精品一区二区三区| 亚洲精品在线免费观看| 国产在亚洲线视频观看| 你懂的免费在线观看网站| 国产精品视频免费一区二区| 久久久久亚洲精品男人的天堂| 亚洲精品免费在线观看|