設備兼容性

  java老鳥們大多應該對java的所謂寫一次到處運行留下了深刻的印象,我們已經習慣了所謂按照某種規范開發,然后寫一次,到處調試的的模式。好吧,非常不幸的是,kjava設備的差異性要遠高于 j2ee中各種應用服務器和平臺之間的差異,現在的規則可能會變成,寫一次, 到處修改。搞不好工作量的三分之一都會花費在這個上面。
  大的廠商,比如nokia和索愛, 會提供定制版本的模擬器以及相關文檔,在定制版本模擬器上運行可以節約一部分工作量,雖然很遺憾的是,他們的速度通常不怎么樣,小問題也比較多。 而其他一些廠商可能完全沒有模擬器和文檔說明,特別是wm上的第三方kvm實現,那就只能自求多福了。

  你必須認識到
   * 模擬器和真機永遠是有差異的, 只有在真機上運行過才知道后果,尤其是運行速度,網絡連接方面。
   * 不同手機的kvm實現之間是有巨大差異的,規范對這種差異基本上不做控制,UI的實現尤甚。

  作為企業應用開發的一個慣例在j2me上也適用,盡早的確定設備型號,并一直持續在這些型號上進行測試。不要到交付用戶的時候再最后做兼容性測試。

內存管理

  大部分手機都是嚴格的內存受限設備,可用內存通常在256k-2m之間。 好吧,老java程序員的懷舊時光又開始了,你會發現在hotspot vm出現之前的一些概念也同樣對kvm有效,主要是關于內存回收部分的代碼,你需要打破你臭美的代碼風格,強制設置一些已經在j2se世界拋棄的東西。
   *  對需要回收的資源,需要強制將變量設置為null, 這樣gc會優先回收。所以對于個頭稍微大點的變量,都記得找個地方設置為null。
   這事情比較極端的做法是甚至你確定不需要某個資源了,給變量重新賦值之前也需要設置為null。比如
   
       Boy boy = new Boy("good");
       boy = null; //這樣gc才會知道先回收good
       boy = new Boy("bad");
   

   *  必要的時候調用System.gc進行強制回收, 信不信由你,在很多機型上它確實很有效。在內存消耗比較大的操作之后,調用這個效果很明顯。
   順便說一句的是,在j2se的hotspot 的實現里,這樣做的結果往往是讓系統呆住。
   *  盡量不要一次使用大型數組,盡可能拆分成小數組操作。
     尤其是對圖像的操作,諸如旋轉之類,很容易內存死光光。
 
以上這三條已經可以讓你的代碼具有典型的異教徒風格了。另外一些final,static,訪問方法和實例變量的差別,確實有一些書籍介紹如何如何,但是據我閱讀的某本書籍中的測試,這些都是跟機型和kvm實現相關的,沒有絕對標準。

   
異常處理
  j2me的異常處理和j2se迥然不同。 一方面是因為設備通常沒有什么控制臺和文件輸出的概念,約束你隨意的打堆棧, 另外一方面,midp中的異常類的規范并不要求異常附帶堆棧信息,只要求異常的堆棧包含類名而已。 這2條讓異常很難準確定位。

 少許幸運的是,一般模擬器都有debug的模式,這種模式一般有附帶不完整的異常堆棧信息,這也是你可以在pc上開發看到一些異常堆棧的原因。但是在手機上則看不到,除非你安裝debug版本的kvm。即便是這種debug模式,也不會附帶常在j2se中出現的文件和行列信息, 問題定位也要繁瑣一些。即便如此,你也應該慶幸可以在模擬器上發現大部分問題。

  最后歸結于設備兼容性的問題, 初次在設備上運行時,發生各種runtimExcepiton的概率非常高,而一個類名很難讓你準確定位問題,所以編程習慣必須有所改變。

  我的做法是
  *  盡可能的對方法中的參數和變量進行檢查。 防止空指針和索引之類的異常出現。
  在j2se中我們一般只強調對入口參數的檢查,不會太強調對過程中變量值的檢查。這樣畢竟會增加代碼量。
  *  盡可能的對一些入口出,網絡部分, ui部分這些和設備依賴比較高部分的代碼還有一些關鍵代碼做runtimeException的捕獲,方便定位調試。

  而在j2se中的開發中,根據Effective java的表述, 對runtimeException,我們應該視為編程性錯誤,應該不做處理,讓其盡早的暴露。問題是在j2me的環境很難暴露準確位置,所以還是自力更生比較現實一點,這樣好過你到時候滿世界的去懷疑異常是從何處代碼而出的。

  *  盡可能多的做單元測試也是個好路子。 要比在手機上去找問題節約時間。
 
== 日志 ==

 受限于設備的特性, j2me中沒法直接把日志輸出到控制臺或者文件. 而j2me的調試困難度決定了一個合理有效的日志機制顯然是必須的,而且應該在程序開發初始就必須認真考慮。

 實現日志的方式大致有3種
  1. c/s模式, 將日志發送回后臺存儲, 在jdj中有篇文章介紹這種模式,優點是查找問題非常方便,在后臺看就好了,缺點當然是資源消耗問題,還有有些錯誤有可能發生在聯網之前,或者聯網處理中。
  2. 將日志輸出到 rms中,  事后通過程序查看,但是注意rms一般都有大小限制,從幾十k到幾百k不等
  3. 將日志輸出到一個屏幕對象, 可以是form也可以是canvas,需要的時候調出來看。也可以和2結合使用。

 我選擇了第三種方式,將日志輸出到一個日志屏幕,日志屏幕附帶了一個sms發送日志的功能,這樣出了問題,可以方便讓用戶直接把日志信息以短信的方式發送給我定位,呵呵, 至于短信費用,哪不是我考慮的問題:)。
 另外為了方便內存的跟蹤, 在測試階段,日志應該可以自動生成一些內存使用情況信息。

  有一些第三方的log4j實現 比如 Jadabs Log4 J2ME,log4jMini, Microlog4j。 有興趣也可以參考一下。