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慢. 不要在需要高速绘制时做

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值