Look into it ~

          present
          隨筆 - 32, 文章 - 0, 評論 - 3, 引用 - 0
          數據加載中……

          Serializing an Image

          Serializing an Image

          Creating an image from an array of data is an easy task, but to create a byte-array of data from an image is a little more complicated. But it's required if you want to send a modified image to a server.

          To create a byte-array of data from an image, we can use the getRGB(..) method in the image class in MIDP 2.0. From the getRGB method we get an int-array of data containing all the ARGB values of each pixel in the image. Integers in java are four bytes, so we need to split each int value into four byte values.

          To mask out each of the bytes in the int we can use the 'AND &' operator and the 'shift-right >>' operator. Here's an example:

          int ARGB = 0xFFFFFFFF;  // AARRGGBB 
          int a = (ARGB & 0xFF000000);
          int r = (ARGB & 0x00FF0000);
          int g = (ARGB & 0x0000FF00);
          int b = (ARGB & 0x000000FF);
          // Here we move each bit to the right.
          a = (a >> 24); // a = 0x000000FF
          r = (r >> 16); // r = 0x000000FF
          g = (g >> 8); // g = 0x000000FF
          b = b;        // b = 0x000000FF

          When we convert the integer to a byte, there are some problems since there are only signed bytes in Java. A byte may contain values between –128 and 127 and from our integer we'll have a value between 0 and 255.

          Here are some conversion examples:

          Integer val 127 = byte val 127. 
          Integer val 128 = byte val –128.
          Integer val 255 = byte val –1.
          byte ba = (byte)(a);  // if a=0x000000FF (255), then ba = -1
          byte br = (byte)(r);
          byte bg = (byte)(g);
          byte bb = (byte)(b);

          We have to loop though each pixel in the image and get each pixel value to our byte-array. When that's done, we can send the image to a server where we can convert the byte-array back to a integer-array and then show our picture.

          So, when we convert the byte back to an integer we have to check if the byte value is less than zero.

          Int a, r, g, b;
          If(ba<0)
               a = 256 – a;

          Now our new integer value will be between 0 and 255 and we just have to use the 'shift-left <<' operator and add the values together to get our new int-array.

          a = (a << 24);
          r = (r << 16);
          g = (g << 8);
          b = (b);
            0xFF000000 (a)
          + 0x00FF0000 (r)
          + 0x0000FF00 (g)
          + 0x000000FF (b)
          = 0xFFFFFFFF (argb)
          int ARGB = a+r+g+b;

          After the integer-array is recreated we can use the createRGBImage(..) method in the Image class to create our image.

          Be aware that the byte-array is quite large as it contains all of the ARGB values for each pixel. If an image is 100*60 px, where each pixel is four bytes, the byte array will be 24kb.

          ImageBytearryConvert.rar

          posted @ 2008-09-11 17:09 LukeW 閱讀(267) | 評論 (0)編輯 收藏

          HTTP頭信息

          HTTP(HyperTextTransferProtocol)是超文本傳輸協議的縮寫,它用于傳送WWW方式的數據,關于HTTP 協議的詳細內容請參 考RFC2616。HTTP協議采用了請求/響應模型??蛻舳讼蚍掌靼l送一個請求,請求頭包含請求的方法、URI、協議版本、以及包含請求修飾符、客戶 信息和內容的類似于MIME的消息結構。服務器以一個狀態行作為響應,相應的內容包括消息協議的版本,成功或者錯誤編碼加上包含服務器信息、實體元信息以 及可能的實體內容。

          通常HTTP消息包括客戶機向服務器的請求消息和服務器向客戶機的響應消息。這兩種類型的消息由一個起始行, 一個或者多個頭域,一個只是頭域結束的空行和可 選的消息體組成。HTTP的頭域包括通用頭,請求頭,響應頭和實體頭四個部分。每個頭域由一個域名,冒號(:)和域值三部分組成。域名是大小寫無關的,域 值前可以添加任何數量的空格符,頭域可以被擴展為多行,在每行開始處,使用至少一個空格或制表符。

          通用頭域
          通用頭 域包含請求和響應消息都支持的頭域,通用頭域包含Cache-Control、 Connection、Date、Pragma、Transfer-Encoding、Upgrade、Via。對通用頭域的擴展要求通訊雙方都支持此擴 展,如果存在不支持的通用頭域,一般將會作為實體頭域處理。下面簡單介紹幾個在UPnP消息中使用的通用頭域。


            Cache-Control頭域
          Cache -Control指定請求和響應遵循的緩存機制。在請求消息或響應消息中設置 Cache-Control并不會修改另一個消息處理過程中的緩存處理過程。請求時的緩存指令包括no-cache、no-store、max-age、 max-stale、min-fresh、only-if-cached,響應消息中的指令包括public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age。各個消息中的指令含義如 下:

          Public指示響應可被任何緩存區緩存。
          Private指示對于單個用戶的整個或部分響應消息,不能被共享緩存處理。這允許服務器僅僅描述當用戶的部分響應消息,此響應消息對于其他用戶的請求無效。
          no-cache指示請求或響應消息不能緩存
          no-store用于防止重要的信息被無意的發布。在請求消息中發送將使得請求和響應消息都不使用緩存。
          max-age指示客戶機可以接收生存期不大于指定時間(以秒為單位)的響應。
          min-fresh指示客戶機可以接收響應時間小于當前時間加上指定時間的響應。
          max-stale指示客戶機可以接收超出超時期間的響應消息。如果指定max-stale消息的值,那么客戶機可以接收超出超時期指定值之內的響應消息。


            Date頭域
          Date頭域表示消息發送的時間,時間的描述格式由rfc822定義。例如,Date:Mon,31Dec200104:25:57GMT。Date描述的時間表示世界標準時,換算成本地時間,需要知道用戶所在的時區。

            Pragma頭域
            Pragma頭域用來包含實現特定的指令,最常用的是Pragma:no-cache。在HTTP/1.1協議中,它的含義和Cache- Control:no-cache相同。

          請求消息
          請求消息的第一行為下面的格式:
          MethodSPRequest-URISPHTTP-VersionCRLFMethod 表示對于Request-URI完成的方法,這個字段是大小寫敏感的,包括OPTIONS、GET、HEAD、POST、PUT、DELETE、 TRACE。方法GET和HEAD應該被所有的通用WEB服務器支持,其他所有方法的實現是可選的。GET方法取回由Request-URI標識的信息。 HEAD方法也是取回由Request-URI標識的信息,只是可以在響應時,不返回消息體。POST方法可以請求服務器接收包含在請求中的實體信息,可 以用于提交表單,向新聞組、BBS、郵件群組和數據庫發送消息。

          SP表示空格。Request-URI遵循URI格式,在此字段 為星 號(*)時,說明請求并不用于某個特定的資源地址,而是用于服務器本身。HTTP- Version表示支持的HTTP版本,例如為HTTP/1.1。CRLF表示換行回車符。請求頭域允許客戶端向服務器傳遞關于請求或者關于客戶機的附加 信息。請求頭域可能包含下列字段Accept、Accept-Charset、Accept- Encoding、Accept-Language、Authorization、From、Host、If-Modified-Since、If- Match、If-None-Match、If-Range、If-Range、If-Unmodified-Since、Max-Forwards、 Proxy-Authorization、Range、Referer、User-Agent。對請求頭域的擴展要求通訊雙方都支持,如果存在不支持的請 求頭域,一般將會作為實體頭域處理。

            典型的請求消息:
          GET http://download.microtool.de:80/somedata.exe
          Host: download.microtool.de
          Accept:*/*
          Pragma: no-cache
          Cache-Control: no-cache
          Referer: http://download.microtool.de/
          User-Agent:Mozilla/4.04[en](Win95;I;Nav)
          Range:bytes=554554-

          上例第一行表示HTTP客戶端(可能是瀏覽器、下載程序)通過GET方法獲得指定URL下的文件。棕色的部分表示請求頭域的信息,綠色的部分表示通用頭部分。

            Host頭域
            Host頭域指定請求資源的Intenet主機和端口號,必須表示請求url的原始服務器或網關的位置。HTTP/1.1請求必須包含主機頭域,否則系統會以400狀態碼返回。

            Referer頭域
          Referer 頭域允許客戶端指定請求uri的源資源地址,這可以允許服務器生成回退鏈表,可用來登陸、優化cache等。他也允許廢除的或錯誤的連接由于維護的目的被 追蹤。如果請求的uri沒有自己的uri地址,Referer不能被發送。如果指定的是部分uri地址,則此地址應該是一個相對地址。

            Range頭域
          Range頭域可以請求實體的一個或者多個子范圍。例如,
          表示頭500個字節:bytes=0-499
          表示第二個500字節:bytes=500-999
          表示最后500個字節:bytes=-500
          表示500字節以后的范圍:bytes=500-
          第一個和最后一個字節:bytes=0-0,-1
          同時指定幾個范圍:bytes=500-600,601-999

          但是服務器可以忽略此請求頭,如果無條件GET包含Range請求頭,響應會以狀態碼206(PartialContent)返回而不是以200 (OK)。

            User-Agent頭域
          User-Agent頭域的內容包含發出請求的用戶信息。

          響應消息
          響應消息的第一行為下面的格式:
          HTTP-VersionSPStatus-CodeSPReason-PhraseCRLF

          HTTP -Version表示支持的HTTP版本,例如為HTTP/1.1。Status- Code是一個三個數字的結果代碼。Reason-Phrase給Status-Code提供一個簡單的文本描述。Status-Code主要用于機器自 動識別,Reason-Phrase主要用于幫助用戶理解。Status-Code的第一個數字定義響應的類別,后兩個數字沒有分類的作用。第一個數字可 能取5個不同的值:

          1xx:信息響應類,表示接收到請求并且繼續處理
          2xx:處理成功響應類,表示動作被成功接收、理解和接受
          3xx:重定向響應類,為了完成指定的動作,必須接受進一步處理
          4xx:客戶端錯誤,客戶請求包含語法錯誤或者是不能正確執行
          5xx:服務端錯誤,服務器不能正確執行一個正確的請求

          響應頭域允許服務器傳遞不能放在狀態行的附加信息,這些域主要描述服務器的信息和 Request-URI進一步的信息。響應頭域包含Age、Location、Proxy-Authenticate、Public、Retry- After、Server、Vary、Warning、WWW-Authenticate。對響應頭域的擴展要求通訊雙方都支持,如果存在不支持的響應頭 域,一般將會作為實體頭域處理。

          典型的響應消息:

          HTTP/1.0200OK
          Date:Mon,31Dec200104:25:57GMT
          Server:Apache/1.3.14(Unix)
          Content-type:text/html
          Last-modified:Tue,17Apr200106:46:28GMT
          Etag:"a030f020ac7c01:1e9f"
          Content-length:39725426
          Content-range:bytes554554-40279979/40279980

          上例第一行表示HTTP服務端響應一個GET方法。棕色的部分表示響應頭域的信息,綠色的部分表示通用頭部分,紅色的部分表示實體頭域的信息。

            Location響應頭
          Location響應頭用于重定向接收者到一個新URI地址。

            Server響應頭
          Server響應頭包含處理請求的原始服務器的軟件信息。此域能包含多個產品標識和注釋,產品標識一般按照重要性排序。

            實體
          請求消息和響應消息都可以包含實體信息,實體信息一般由實體頭域和實體組成。實體頭域包含關于實體的原信息,實體頭包括Allow、Content- Base、Content-Encoding、Content-Language、 Content-Length、Content-Location、Content-MD5、Content-Range、Content-Type、 Etag、Expires、Last-Modified、extension-header。extension-header允許客戶端定義新的實體 頭,但是這些域可能無法未接受方識別。實體可以是一個經過編碼的字節流,它的編碼方式由Content-Encoding或Content-Type定 義,它的長度由Content-Length或Content-Range定義。

            Content-Type實體頭
          Content-Type實體頭用于向接收方指示實體的介質類型,指定HEAD方法送到接收方的實體介質類型,或GET方法發送的請求介質類型 Content-Range實體頭
          Content-Range實體頭用于指定整個實體中的一部分的插入位置,他也指示了整個實體的長度。在服務器向客戶返回一個部分響應,它必須描述響應覆蓋的范圍和整個實體長度。一般格式:
          Content-Range:bytes-unitSPfirst-byte-pos-last-byte-pos/entity-legth 


          例如,傳送頭500個字節次字段的形式:Content-Range:bytes0- 499/1234如果一個http消息包含此節(例如,對范圍請求的響應或對一系列范圍的重疊請求),Content-Range表示傳送的范圍, Content-Length表示實際傳送的字節數。

            Last-modified實體頭

          應答頭 說明
          Allow 服務器支持哪些請求方法(如GET、POST等)。
          Content-Encoding 文 檔的編碼(Encode)方法。只有在解碼之后才可以得到Content-Type頭指定的內容類型。利用gzip壓縮文檔能夠顯著地減少HTML文檔的 下載時間。Java的GZIPOutputStream可以很方便地進行gzip壓縮,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet應該通過查看Accept-Encoding頭(即request.getHeader("Accept- Encoding"))檢查瀏覽器是否支持gzip,為支持gzip的瀏覽器返回經gzip壓縮的HTML頁面,為其他瀏覽器返回普通頁面。
          Content-Length 表 示內容長度。只有當瀏覽器使用持久HTTP連接時才需要這個數據。如果你想要利用持久連接的優勢,可以把輸出文檔寫入 ByteArrayOutputStram,完成后查看其大小,然后把該值放入Content-Length頭,最后通過 byteArrayStream.writeTo(response.getOutputStream()發送內容。
          Content-Type 表示后面的文檔屬于什么MIME類型。Servlet默認為text/plain,但通常需要顯式地指定為text/html。由于經常要設置Content-Type,因此HttpServletResponse提供了一個專用的方法setContentTyep。
          Date 當前的GMT時間。你可以用setDateHeader來設置這個頭以避免轉換時間格式的麻煩。
          Expires 應該在什么時候認為文檔已經過期,從而不再緩存它?
          Last-Modified 文 檔的最后改動時間。客戶可以通過If-Modified-Since請求頭提供一個日期,該請求將被視為一個條件GET,只有改動時間遲于指定時間的文檔 才會返回,否則返回一個304(Not Modified)狀態。Last-Modified也可用setDateHeader方法來設置。
          Location 表示客戶應當到哪里去提取文檔。Location通常不是直接設置的,而是通過HttpServletResponse的sendRedirect方法,該方法同時設置狀態代碼為302。
          Refresh 表示瀏覽器應該在多少時間之后刷新文檔,以秒計。除了刷新當前文檔之外,你還可以通過setHeader("Refresh", "5; URL=http://host/path")讓瀏覽器讀取指定的頁面。
          注 意這種功能通常是通過設置HTML頁面HEAD區的<META HTTP-EQUIV="Refresh" CONTENT="5;URL=http://host/path">實現,這是因為,自動刷新或重定向對于那些不能使用CGI或Servlet的 HTML編寫者十分重要。但是,對于Servlet來說,直接設置Refresh頭更加方便。

          注意Refresh的意義是“N秒之后 刷新本頁面或訪問指定頁面”,而不是“每隔N秒刷新本頁面或訪問指定頁面”。因此,連續刷新要求每次都發送一個Refresh頭,而發送204狀態代碼則 可以阻止瀏覽器繼續刷新,不管是使用Refresh頭還是<META HTTP-EQUIV="Refresh" ...>。

          注意Refresh頭不屬于HTTP 1.1正式規范的一部分,而是一個擴展,但Netscape和IE都支持它。
          Server 服務器名字。Servlet一般不設置這個值,而是由Web服務器自己設置。
          Set-Cookie 設置和頁面關聯的Cookie。Servlet不應使用response.setHeader("Set-Cookie", ...),而是應使用HttpServletResponse提供的專用方法addCookie。參見下文有關Cookie設置的討論。
          WWW-Authenticate 客 戶應該在Authorization頭中提供什么類型的授權信息?在包含401(Unauthorized)狀態行的應答中這個頭是必需的。例如, response.setHeader("WWW-Authenticate", "BASIC realm=\"executives\"")。
          注意Servlet一般不進行這方面的處理,而是讓Web服務器的專門機制來控制受密碼保護頁面的訪問(例如.htaccess)。

          posted @ 2008-09-10 12:05 LukeW 閱讀(242) | 評論 (0)編輯 收藏

          j2me獲取系統信息

          在J2ME開發中,我們經常需要和手機系統進行交互,獲得一些和系統相關的信息,在J2ME API設計中,提供了一系列的系統屬性
          表1   CLDC、MIDP和JTWI屬性
          屬性名稱
          屬性作用
          microedition.profiles
          代表手機支持的MIDP版本,返回格式值為“MIDP-1.0”或“MIDP-2.0”
          microedition.configuration
          代表手機支持的CLDC版本,返回格式值為“CLDC-1.0”或“CLDC-2.0”
          microedition.locale
          代表手機所在的國家或地區,返回值格式為“en-US”
          microedition.platform
          代表手機的品牌和型號,Nokia手機的返回值格式為“Nokia6310i/4.42”
          microedition.encoding
          代表手機默認的字符集名稱,返回值格式為“ISO-8859-1”
          microedition.commports
          代表手機可以使用的串口列表,返回值中各個串口之間使用逗號分隔
          microedition.hostname
          MIDP2.0定義,代表本地主機名稱,需要手機支持。
          microedition.jtwi.version
          代表手機支持的JTWI版本,值必須是“1.0”
           表2 可選包屬性
          屬性名稱
          屬性作用
          microedition.media.version
          代表手機支持的MMAPI版本,如果不支持則返回null
          microedition.pim.version
          代表手機支持的PIM API版本,如果不支持則返回null
          microedition.m3g.version
          代表手機支持的M3G API版本,如果不支持則返回null
          microedition.location.version
          代表手機支持的Location API版本,如果不支持則返回null
          Bluetooth.api.version
          代表手機支持的BT API版本,如果不支持則返回null
          microedition.io.file.
          FileConnection.version
          代表手機支持的FC API版本,如果不支持則返回null
          microedition.global.version
          代表手機支持的Mobile Internationalization API(JSR-238)版本,如果不支持則返回null
          microedition.chapi.version
          代表手機支持的CH(Content Handler) API(JSR211)版本,如果不支持則返回null
          microedition.sip.version
          代表手機支持的SIP API版本,如果不支持則返回null
           表3 MMAPI屬性
          屬性名稱
          屬性作用
          supports.mixing
          代表手機是否支持混音(同時播放多個Player),返回值為“true”或“false”
          supports.audio.capture
          代表手機是否支持聲音捕獲(錄音),返回值為“true”或“false”
          supports.video.capture
          代表手機是否支持視頻捕獲(錄像),返回值為“true”或“false”
          supports.recording
          代表手機是否支持記錄(record),返回值為“true”或“false”
          audio.encodings
          代表手機支持的聲音格式,返回值格式為“encoding=audio/wav”,多個格式之間使用至少一個空格進行間隔
          video.encodings
          代表手機支持的視頻格式,返回值格式為“encoding=video/3gpp”,多個格式之間使用至少一個空格進行間隔
          video.snapshot.encodings
          代表手機使用getSnapshot方法獲得的視頻快照格式,返回值格式為“encoding=png”,多個格式之間使用至少一個空格進行間隔
          streamable.contents
          代表手機支持的流媒體格式,返回null代表不支持
          表4 Wireless Messaging API屬性
          屬性名稱
          屬性作用
          wireless.messaging.sms.smsc
          代表手機發送短信時的短信服務中心號碼
          表5 FileConnection API
          屬性名稱
          屬性作用
          fileconn.dir.photos
          代表手機中存儲照片和其它圖片的目錄,例如“file:///c:/My files/ Images /”
          fileconn.dir.videos
          代表手機中存儲視頻的目錄,例如“file:///c:/My files/Video clips/”
          fileconn.dir.tones
          代表手機中存儲聲音的目錄,例如“file:///c:/My files/Tones/”
          fileconn.dir.memorycard
          代表手機中存儲卡的根目錄。例如“file:///d:/”
          fileconn.dir.private
          (Nokia S40不支持) 
          代表手機中MIDlet的私有工作目錄,例如“file:///c:/System/MIDlets/[1015f294]/scratch”
          fileconn.dir.photos.name
          代表手機中圖片目錄的名稱,例如“Images”
          fileconn.dir.videos.name
          代表手機中視頻目錄的名稱,例如“Video clips”
          fileconn.dir.tones.name
          代表手機中聲音目錄的名稱,例如“Sound clips”
          file.separator
          代表手機中的文件分隔符,例如“/”
          fileconn.dir.memorycard.name
          代表手機中存儲卡的名稱,例如“Memory card”
           使用這些屬性,可以獲得在程序運行過程中需要的很多和系統相關的信息,也可以使用表2中的屬性來獲得手機是否支持對應的可選包等信息。
          實際使用示例:String name = System.getProperty(“microedition.platform”);

          注意:如果需要獲得JVM或jad文件中的信息,需要使用MIDlet類中的getAppProperty方法,其屬性名則需要查閱jad文件的設定,和本文所述的屬性名無關。

          posted @ 2008-08-28 16:43 LukeW 閱讀(288) | 評論 (0)編輯 收藏

          HTTP請求頭信息

          HTTP客戶程序(例如瀏覽器),向服務器發送請求的時候必須指明請求類型(一般是GET或者POST)。如有必要,客戶程序還可以選擇發送其他的請求 頭。大多數請求頭并不是必需的,但Content-Length除外。對于POST請求來說Content-Length必須出現。

          下面是一些最常見的請求頭:

          Accept:瀏覽器可接受的MIME類型。
          Accept-Charset:瀏覽器可接受的字符集。
          Accept-Encoding:瀏覽器能夠進行解碼的數據編碼方式,比如gzip。Servlet能夠向支持gzip的瀏覽器返回經gzip編碼的HTML頁面。許多情形下這可以減少5到10倍的下載時間。
          Accept-Language:瀏覽器所希望的語言種類,當服務器能夠提供一種以上的語言版本時要用到。
          Authorization:授權信息,通常出現在對服務器發送的WWW-Authenticate頭的應答中。
          Connection: 表示是否需要持久連接。如果Servlet看到這里的值為“Keep-Alive”,或者看到請求使用的是HTTP 1.1(HTTP 1.1默認進行持久連接),它就可以利用持久連接的優點,當頁面包含多個元素時(例如Applet,圖片),顯著地減少下載所需要的時間。要實現這一點, Servlet需要在應答中發送一個Content-Length頭,最簡單的實現方法是:先把內容寫入ByteArrayOutputStream,然 后在正式寫出內容之前計算它的大小。
          Content-Length:表示請求消息正文的長度。
          Cookie:這是最重要的請求頭信息之一,參見后面《Cookie處理》一章中的討論。
          From:請求發送者的email地址,由一些特殊的Web客戶程序使用,瀏覽器不會用到它。
          Host:初始URL中的主機和端口。
          If-Modified-Since:只有當所請求的內容在指定的日期之后又經過修改才返回它,否則返回304“Not Modified”應答。
          Pragma:指定“no-cache”值表示服務器必須返回一個刷新后的文檔,即使它是代理服務器而且已經有了頁面的本地拷貝。
          JAVA手機網[www.cnjm.net]

          Referer:包含一個URL,用戶從該URL代表的頁面出發訪問當前請求的頁面。
          User-Agent:瀏覽器類型,如果Servlet返回的內容與瀏覽器類型有關則該值非常有用。
          UA-Pixels,UA-Color,UA-OS,UA-CPU:由某些版本的IE瀏覽器所發送的非標準的請求頭,表示屏幕大小、顏色深度、操作系統和CPU類型。
          有關HTTP頭完整、詳細的說明,請參見http://www.w3.org/Protocols/ 的HTTP規范。

          java 讀取方法

            Enumeration headerNames = request.getHeaderNames();
                   while(headerNames.hasMoreElements()) {
                       String headerName = (String)headerNames.nextElement();
                       out.println("<p>"+headerName+"  "+request.getHeader(headerName)+"</p>");
                   }

          posted @ 2008-08-20 13:58 LukeW 閱讀(167) | 評論 (0)編輯 收藏

          期待eclipse RCP:Design, Coding and Packaging 第二版

          eclipse_rcp_book_cover

          《Eclipse Rich Client Platform – Design, Coding and Packaging》是在Eclipse 3.1發布以后,針對 Eclipse RCP 平臺的一本非常重要,也非常有用的書。 最近,這本書的作者們開始了第二版的編寫,將以最新的 Eclipse 3.4 為基礎,并且預計在08年年底正式發布。 新書的作者透露,第二版中除了以3.4為基礎,還將加入很多新東西:

          非常期待著這本書。

          posted @ 2008-08-20 10:13 LukeW 閱讀(140) | 評論 (0)編輯 收藏

          eclipse真機調試J2me程序

          簡單記錄一下遇到的幾個問題:

          1. 真機調試其實是廠商SDK根據JAVA的調試API層實現的.

          2. 要注意JAD文件中字段的長度不要過長, 否則會報錯, 無法調試.

          3. 相比較, netbeans進行真機調試要方便一些. 當然eclipse應該也沒問題(懶得實驗了..).

          posted @ 2008-08-15 15:22 LukeW 閱讀(327) | 評論 (0)編輯 收藏

          J2me的List總結

          List控件是使用頻率非常高的顯示控件之一了。但是最近發現它的一點不足。
          那就是getSelectedIndex()函數,一般情況下它都能正常工作。唯有在List處于復選模式(MULTIPLE)時,使用該函數無法獲得當前高亮條選中索引,而總是返回-1。

          參考List控件的源代碼,可以發現,List類實現了Choice接口,并且包含一個ChoiceGroup成員。它才是實現List大部分功能的大功臣。
          List類的getSelectedIndex()方法,實際上就是ChoiceGroup的getSelectedIndex()方法。大家可以參考Doc中關于ChoiceGroup的getSelectedIndex()方法的如下部分。
          “For ChoiceGroup objects of type MULTIPLE, this always returns -1 because no single value can in general represent the state of such a ChoiceGroup.”

          就是說,List在多選模式(MULTIPLE)下,我們是無法獲取當前高亮條所在項的索引值的。
          當然,你可以自己數數。

          也許你覺得這個問題不算嚴重,也許吧。但我覺得對于程序員來說,最嚴重的問題就是理解發生偏差。
          比如我,在發現這個問題之前。憑借多年的編程經驗,我很確定很確定的認為,這個getSelectedIndex()永遠能夠獲得當前光標所指項的索引值。
          ……當錯誤來臨時,我百思不得其解。最后,花了好些時間去調試才發現,那個值總等于-1。操!花了太多時間去猜測原本正確的代碼。
          我只想告訴大家,真正耗費時間最多,讓人最惡心的錯誤,往往就是這樣的問題。再操!

          那么有什么簡單的解決辦法么?
          我可以很負責任的告訴你,自己寫一個多選的List控件吧,記住不要讓getSelectedIndex()總返回-1。即使是多選,有時候也是需要這個值的。

          也許你想繼承List,然后重載getSelectedIndex()方法。但你無法重載List的keyPressed方法(其實List等Screen控件都用Canvas寫的)。
          ……或許還能想到別的什么好辦法。不過我的選擇是自己寫一個List控件代替它(如果對它感興趣,請回復,改天我在弄出來吧)。

          至于List的其它功能,就沒什么重復的必要的,看看文檔吧。

          posted @ 2008-08-15 15:20 LukeW 閱讀(300) | 評論 (0)編輯 收藏

          Vector 總結

          Vector是在java編程中比較常用的動態數組。一直以為它是個數組的鏈表,當內存不夠用了,就新申請一個capacityIncrement大小的數組,連到原來的鏈表上。
          在仔細閱讀源代碼后發現,Vector并沒有任何鏈表的性質。它是一個純粹的數組。當內存不夠用時,就重新初始化一個容量較大新數組,然后使用System.arraycopy()函數將原有的數組copy到新的數組當中。

          System.arraycopy()是一個由系統平臺來實現的函數,這樣的系統調用性能是比較高的。
          即使如此,我們在寫程序時,注意initialCapacity(初始容量)和capacityIncrement(增量)的設置,將會有效的減少重新定義數組并且拷貝數組的次數。

          例如:
          Vector v = new Vector(1010);//初始容量為10,增量10
          Integer[] ints = new Integer11;
          for (int i = 0; i < ints.length; i++) {
          ints 
          = new Integer(i);
          v.addElement(ints);
          }

          在這里,當v添加第11個Integer的時候,v就會自動創建一個長度為20的數組(當前容量+增量),以后每次裝滿數組,都會重新按增量追加數組長度。
          所以,設置一個合適的初始容量和增量,將會提高Vector的效率。千萬別像我一樣,把它當做鏈表。因為鏈表在增長空間時是不會影響到以前使用的空間和數據的。

          我想指出一點,因為Vector中存儲的,實際上都是Object變量,大家可以把它理解為指針。重新初始化Vector內置的數組并且拷貝,相當于對一個指針數組進行操作,并不等同于對輸入類型的重新分配內存。
          就是說Vector的重新分配,不論進行多少次都不涉及到Integer對象的創建,拷貝等工作。它只是重新創建并拷貝“指針”數組,也就是Object數組。
          此外,java中有一個容易被忽視的基本概念。當某個對象再沒有指向該對象的引用時,垃圾回收器才會自動將其自動釋放。不小心使用,很容易給程序造成內存問題。
          例如:

          Vector v = new Vector(1010);//初始容量為10,增量10
          Integer[] ints = new Integer11;
          for (int i = 0; i < ints.length; i++) {
          ints 
          = new Integer(i);
          v.addElement(ints);
          }
          ints 
          = null;//對它的釋放將造成數組元素的釋放。但是由于v中還保存有元素的引用,所以這些Integer對象并不會被回收。
          我強調這個問題,是因為曾經寫過一段代碼:
          Image img = Image.createImage(”/xxx.png”);
          Image img2 = img;
          這張圖片非常大,在使用完img之后,我釋放掉它,然后重新申請另一個圖片。于是,內存爆了。因為img2仍然持有xxx.png的引用,所以無法釋放。
          Vectro中存儲的也是引用,所以在使用時應該更加注意編程規范,以免發生類似的問題。其實應該盡量避免使用多個引用。

          上面說了這些題外話,正是想警告各位程序員,Vector是一個可變的Object數組,一個引用數組。所以請大家使用時要小心,別想當然的以為它是一個容器,它里面存儲的可不是對象,而是引用。
          而且,在釋放曾經加入到vector的對象時,對象本身并不會被真正釋放,得到回收。只是原有的引用無法再使用罷了。

          最后還有一點技巧。
          應該盡量使用索引獲取對象,避免使用IndexOf()方法。把它當做堆棧來使用時更應該注意,要避免使用insertElementAt()方法。
          此外,j2me中的Stack類是基于Vector實現的,使用時也要留心。

          posted @ 2008-08-15 15:19 LukeW 閱讀(192) | 評論 (0)編輯 收藏

          漢字轉拼音

               摘要: 在網上參考了一些漢字轉換到拼音的資料。思路應該只有以下兩種。 1,查表法。這樣做需要一個龐大的映射表,在j2me環境下不大合適。不過效果好,有些還支持多音字。 2,使用GB字庫的映射關系。因為GB2312及其擴展GBK的漢字編碼都根據區位于拼音存在映射關系。 實際上網絡上的大部分文章都是根據第二種方法來實現的。 我也是采用這種方法,因為它基本上可以利用GB2312字庫,直接映射成拼音。...  閱讀全文

          posted @ 2008-08-15 15:15 LukeW 閱讀(415) | 評論 (0)編輯 收藏

          GB2312轉換Unicode

          之前的文章介紹了在j2me環境下GB2312轉換為UTF-8的方法。
          后來繼續對編碼及char類型進行學習,發現一些有趣的問題。
          首先java環境下的char類型變量,實際上就是以unicode方式存儲的。
          所以以下方法有效:

          輸入unicode編碼的byte數組,即可兩兩拼接成一個char。
          而String類型實際上就是在char數組的基礎上衍生出來的。大家可以參考cldc的源代碼。
          public static String read_Uni(byte[] word_unicode) {
                  StringBuffer stringbuffer 
          = new StringBuffer("");
                  
          for (int j = 0; j < word_unicode.length;) {
                      
          int l = word_unicode[j++];
                      
          int h = word_unicode[j++];
                      
          char c = (char) ((l & 0xff| ((h << 8& 0xff00));
                      stringbuffer.append(c);
                  }
                  
          return stringbuffer.toString();
              }


          j2me環境下也是如此。
          所以在第一次給出的轉換類中,提供的gb2312到utf-8直接轉換的快速方法?,F在看來是畫蛇添足了。

          根據以上經驗,更新轉換類如下:
          public class HGB2312 {
           
                  
          private byte[] map = new byte[15228];
           
                  
          public HGB2312() throws Exception {
                      InputStream is 
          = getClass().getResourceAsStream("/gb2u.dat");
                      is.read(map);
                      is.close();
                  }
           
                  
          public String gb2utf8(byte[] gb) {
                      StringBuffer sb 
          = new StringBuffer();
                      
          int c, h, l, ind;
                      
          for (int i = 0; i < gb.length;) {
                          
          if (gb[i] >= 0) {
                              sb.append((
          char) gb[i++]);
                          } 
          else {
                              h 
          = 256 + gb[i++];
                              l 
          = 256 + gb[i++];
                              h 
          = h - 0xA0 - 1;
                              l 
          = l - 0xA0 - 1;
                              
          if (h < 9) {
                                  ind 
          = (h * 94 + l) << 1;
                                  c 
          = (byte2Int(map[ind]) << 8 | byte2Int(map[ind + 1]));
                                  sb.append((
          char) c);
                              } 
          else if (h >= 9 && h <= 14) {
                                  sb.append((
          char0);
                              } 
          else if (h > 14) {
                                  h 
          -= 6;
                                  ind 
          = (h * 94 + l) << 1;
                                  c 
          = (byte2Int(map[ind]) << 8 | byte2Int(map[ind + 1]));
                                  sb.append((
          char) c);
           
                              } 
          else {
                                  sb.append((
          char0);
                              }
                          }
                      }
                      
          return sb.toString();
                  }
           
                  
          private int byte2Int(byte b) {
                      
          if (b < 0) {
                          
          return 256 + b;
                      } 
          else {
                          
          return b;
                      }
                  }
              }


          這個方法明顯要比第一次快很多了,直接查表,然后拼接成String,不需要轉換成utf-8編碼。

          數據文件請在http://download.csdn.net/source/263609獲取

          總之,java中的char類型實際上是存儲了unicode編碼。目前在nokia 5300上測試通過。
          我覺得其它機器也應該是這樣。如果哪位大俠知道這方面的資料,請賜教。

          posted @ 2008-08-15 14:58 LukeW 閱讀(614) | 評論 (0)編輯 收藏

          僅列出標題
          共3頁: 上一頁 1 2 3 下一頁 
          主站蜘蛛池模板: 喀喇| 荃湾区| 太保市| 德安县| 定兴县| 高雄县| 屏山县| 嘉荫县| 黄平县| 隆化县| 桐城市| 沅江市| 永平县| 延长县| 库伦旗| 朔州市| 台州市| 大城县| 东丽区| 辛集市| 红河县| 小金县| 永川市| 黎川县| 海盐县| 铜川市| 炎陵县| 靖宇县| 乌苏市| 彭州市| 依兰县| 乡城县| 霸州市| 龙口市| 那曲县| 湾仔区| 土默特右旗| 吉木萨尔县| 辽宁省| 蒙城县| 肇东市|