下面记载的都是手机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, 很奇怪的208×208屏幕,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慢. 不要在需要高速绘制时做