J2ME機型適配中的各種問題總結

下面記載的都是手機java實現中各種奇怪的毛病,bug,或者……特性,是根據某項目的開發經驗總結出來的。但是涵蓋的手機型號還是有限。因此很有可能某些“特性”會存在於更多的採用了相同JVM(比如平臺相同、生產廠商)的手機上。


                                                       == 早期S60的內存泄漏 ==
這個bug可以上溯至2003年,甚至更早。表現爲java應用中如果使用了Class.getResourceAsStream("本地文件")無法釋放其佔用的內存,是的,沒有任何辦法,無論是調用獲得的的InputStream實例的close()或將其設爲null,甚至顯式強制System.gc(),都沒有效果。結果就是至少和本地文件同尺寸的內存成爲了無法回收的垃圾。這個問題還影響到以Class.getResourceAsStream()爲基礎的Image.createImage()(這個是最要命的,如何能夠不使用圖片資源呢!)。
這個bug據說在新的S60上已經解決了。但是Nokia3230(4.0526.2ch)、Nokia7610(6.0525.0ch)都存在這個問題。對於這些個有問題的機型,在java程序中是無法完美解決這個問題的,只能儘量避免。比如集中、統一載入資源,永不釋放(也就是說,儘量控制泄漏的次數)。當然,這會對已有代碼造成很大影響。畢竟手機java應用是內存受限系統的典型,大多數情況下,珍貴的內存中只保留需要的資源。


                                                     == 鍵盤響應事件 ==
在MIDP1中,獲取鍵盤事件只能自己實現Canvas.keyPressed()。但是MotorolaE398和SonyEricssonK700c的實現卻很奇怪。表現爲左右軟鍵有可能在這個方法中捕獲不到。而是否能夠成功捕獲,取決於keyPressed()方法中代碼的行數……
我承認我沒徹底搞清楚這其中的玄機。鬼知道Motorola和SonyEricsson是怎麼實現的JVM。我只知道把keyPressed中的所有代碼提取到另外一個函數中,在keyPressed只把參數傳遞給新函數,問題就消失了……

                                               == 超慢的drawRegion ==


除了N-Gage QD,幾乎所有的NokiaS60手機都實現了MIDP2的支持。MIDP2中,最爲重要的幾個特性之一就是Graphics.drawRegion。這個API可以方便的將圖片旋轉、剪切之後畫到畫布上。
但是,這個API在Nokia3230、Nokia7610等手機上的實際性能表現讓人實在不敢恭維。於是,這個最重要的API成了擺設…
…沒什麼怎麼辦,只能急需延用MIDP1的做法,自己實現剪切和旋轉,或者像我一樣懶,直接要求美工把旋轉之後的圖片全都做出來……


                                      == 詭異的內存容量==


按照官方Spec,Java在Nokia3125上的可用內存(即Java Heap Size)爲512k。但是實際測試的結果是,Nokia3125只有412k左右的實際內存,相差整整100k。不過好在Nokia3125並不是種市場保有量很高的型號。但是它是我正在使用的型號……


                                                       == 無法repaint ==
這個問題只存在於SonyEricssonK700c。表現爲在keyPressed()中調用repaint()進行屏幕重畫沒有任何反應。
解決辦法是,在keyReleased()中補一個repaint()……


                                                       == UTF8 ==
還是SonyEricssonK700c的問題。問題存在於new String(byte[], charset)上。也就是說,當獲得了某個byte[],並希望用UTF8作爲字符集將其轉換爲字符串的時候,使用上述方法在SonyEricssonK700c上會出現丟失字符的現象。這個現象很詭異,以至於我目前沒有搞清楚什麼情況下會丟失字符(我甚至專門寫了個測試程序在真機上跑,得出的結論是丟失字符的原因可能會很複雜,簡單的拿被丟掉字符附近的一個子串來測沒有任何問題)。
幸虧還是有解決辦法的。不用new String就完了,而要用更加麻煩的辦法,比如像我一樣,用ByteArrayInputStream,外面套InputStreamReader(bais, "UTF8"),然後用StringBuffer一個一個char讀進來,最後再toString()……


                                                    == 不可靠的copyArea ==


這是Motorola機器上的問題,V3和E398都有。copyArea是Graphics的作整塊屏幕像素copy的常用API(2D動態背景的遊戲幾乎是必不可少)。按照Sun官方的Spec,手機廠商有義務來保證其API實現不存在覆蓋衝突問題。但是Motorola顯然做得不夠好。在Motorola手機上使用這個API會隨機產生貼圖混亂的情況……
解決辦法是自己實現另外一套機制。比如使用另外一張至少和屏幕同樣大小的Image作爲緩衝,用兩次drawImage來替代copyArea……不過這個方法顯而易見的缺點是消耗了更多的內存(那可是不小於屏幕尺寸的Image啊!)。如果內存實在吃緊,只能退而再求其次,作爲緩衝的Image繼續縮水,drawImage的次數繼續增加……不過這個時候需要自己手工解決覆蓋衝突……

                                                       == 無法安靜下來的3220 ==


不知道這個問題是不是在S40平臺上都有,手裏S40又支持MIDI的手機實在是太少了……
3220的一個很明顯的特徵就是聲音大。以至調用了VolumeControl.setLevel(0)之後還是有聲音,和Sun官方的Spec完全不符……沒辦法,只能在需要靜音的時候,再補一個VolumeControl.setMute(true)。

                                                               == 永不ready ==


這是一段手機java獲取網絡數據的常用代碼:while(InputStream.ready()) { InputStream.read() }。
但是經測試,在Nokia3230上,這個ready永遠返回false……沒辦法,如果不改上述代碼的話,就自己實現一個繼承類吧




補充:
nokia

1. 老40的class限制大概在105k左右(所有的class加起來,混吆後,未壓縮的大小),超出一點,連構造子也進不去了,就是說,classloading的時候就out of memory了

2. 6230i, 很奇怪的208x208屏幕,40系統,聲音播放與40兼容, 不能servicerepaints, 否則聲音播放有問題

3. 7370 ,command不在左右邊而在中間, 聲音的inputstream關閉後聲音放不放出來,不能servicerepaints, 否則聲音播放卡住

4. 60進入後立即退出, 用midp1.0重新編譯試試, 60, fullcanvas如果從沒有setclip,有一定的機率屏幕下方放不出

5.6680:問題:運行速度極慢 解決方法:重啓. 此機使用final變量(方法內部定義的)會有莫名其妙的問題,變量不是定義時的數值。問題:打進入電話後不pauseApp,遊戲音樂不停,沒有電話鈴聲,解決方法:用hidennotify,在其中釋放聲音

6. j2me 反覆調用Graphics方法是導致nokia40運行緩慢的主要原因, 這一點在橫軸卷頻遊戲中尤其明顯,相比之下,servicerepaints和gc兩個方法並不緩慢
解決方法,建立一個image,將背景畫在其上,每次卷軸都保留需要的部分,更新需更新的部分,然後數次繪製此image拼成背景,能有效提高性能

7.如何對抗nokia 3650 存儲已滿
一次性io操作
createimage , getresourceasstream 一次性做完扔在內存裏,3650 io 會內存泄漏
image.getgraphics()
此操作每次創建新graphics, image不gc掉graphics也不會gc掉,每個image只.getgraphics一次
3650,7650,QD如果有這樣問題同上處理

8. nokia s40(新)在paint所在線程放聲音鎖死,不知爲什麼,不是所有遊戲都會發生,但是如果發生了,那就必然而不是隨機發生。

9 新40對midi的兼容性不是很好,如果聲音放不出需音效修改

10 qd遊戲切出去後不能從百寶箱裏選擇進入,但可以長按菜單鍵切回. 在paint之間sleep即可在百寶箱裏切回seimens

1. SX 問題:mmapi放聲音老是device unavailible,解決方法:換成nokia sound(wav)

2. SX 程序第一次執行沒有問題,退出後再進直接nullpointer except ,去掉所有static後ok

三菱

1.m750 循環前後需要加同步與限幀才能打進電話

阿爾卡特

1.ot556 getGraphics 極其慢, rms沒有作用.

NEC

1.nec 820也是個需要手動gc的主,  日韓手機之通病-_-!

2. nec 820 class Media; getAudioClip太多次有可能導致audioclip放了一點點聲音就斷掉.也有可能不發生這個事情. 解決方法: 一次建立所有的audioclip

3. nec 820 class audioClip; 設置的loopcount在stop以後失效 解決方法:  重新設置loopcount會出exception,用audiolistener

4.nec830可能認不出一些mid文件,讓音效修改之


samsung
1.d508 drawline有問題,drawrect據說也有問題,fill rect好的command 底下那一塊繪製有毛病,一會紅一會黑的,在那繪製有莫名奇妙的問題

moto

1. E2, 只能同時打開4個player, 持續關閉和創建player,在半小時到一小時後會莫名其妙退出. 播放聲音在一開始會卡一下, 聲音超級難聽,還號稱音樂手機,垃圾

2.  L6, 14x的icon

索愛

1.t628 系統資源不足,要求我刪文件,刪無可刪

2, k300,k500系列整圖卷屏時, 當整圖畫在左上角時有可能位置比實際座標偏左了一點, 看上去背景向左邊閃了一下,如果出現這個問題可以將整圖向左邊沒有空隙地貼牢

imode (9xx)

1.應該總是getcolorbyrgb,不要想當然的用0xff1234之類,可能異常或者無顏色

2.載入240*240更大的圖會出現圖片問題

3.有時侯大圖片莫名其妙顯示不了

4.imode手機遊戲必定涉及網絡,必須正確處理網絡不可用的情況

5.usenetwork的值是http

6.usebrowser的值是launch,如果你需要打開瀏覽器的話

7.在http通信時按通話鍵會切斷這個http連接

8.播放聲音時必須捕作異常,並在捕獲後重做前一步, 儘管它並不規定必須處理此異常

vodafone sharp

1.讀取寫入rms慢. 不要在需要高速繪製時做

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章