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了
不同手机的可用内存、最大jar文件都有要求,例如Nokia S40的大部分手机支持的最大jar文件为64K,最大可用内容为210K。
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慢. 不要在需要高速绘制时做
2、修改按键值
这是另一个重要的方面。确保游戏能够正常的操作的前提条件。比如NOKIA的机型的左右软键分别是-6,-7,而Motorola的C650的左右软键就是-21,-22。所以这种差别是无法回避的。
4、解决不同手机的BUG
最头疼的事情也就是这个了。会出现一些莫名其妙的错误。明明在这个手机上运行的很好。可是到另外一个手机上就出现意想不到的错误。比如无法安装。图片无法显示。玩到某个地方死机。声音无法播放等等。遇到问题先不要着急。冷静的回想一下代码和上一次修改的过程。如果都排除人为原因。那就从内存 和图片 来考虑。有些时候 repaint() 和ServiceRepaints() 也会出现问题。比如NOKIA 新 S60系统。 而且考虑问题不要太片面。因为游戏本身就是一个环环相扣的过程。
另外还要说说手机内存的处理。这是个经典的话题。什么String的使用,System.gc()之类的。以及将无用的对象设置为NULL。这些网上都有相关的讨论。以及static的用法。提一个地方。就是在手机加载图片时。手机中计算图片占用的内存是:图片长×图片宽×图片颜色数×2。甚至一幅透明的图片和一幅单色的同样尺寸的图片占用的内存都是很接近的。另外要少用Graphics.drawString() 。有空可以自己写程序测试一下。如果你写了一篇文字。用了N个这个语句。那就应该看看。是否需要替换成一个String数组。或是做成图片占内存更少一些。
MIDP手机程序的标准图片格式是PNG(便携式网络图片格式)。这里值得注意的是,不同的手机平台对于图片的要求也满“挑食”的,同样是PNG格式却不一定适用于所有平台。
在这里我推荐一个工具:Image Optimizer。它可以在不影响图象品质的前提下将图象减肥,最高可减少50%以上
要把图片加载到你的应用程序中,需要调用Image.createImage()这个函数,并且需要做相关的异常处理,所以我一般会在MIDlet中定义一个工具函数,LoadImage()
具体代码如下:
//加载图片
public Image LoadImage(String path)
{
try
{
return Image.createImage(path); //成功则返回图片对象
}
catch(Exception e)
{
e.printStackTrace(); //不成功则打印错误信息并返回空值
return null;
}
}
绘图技巧我们通常做游戏是免不了需要使用Canvas类的,他就像一张空白的画布,我可以在上面描绘出我们的游戏主画面。但是游戏是一个连续动画的过程,而许多动画效果的优劣都取决于低级Canvas类的执行速度。当游戏的某一状态改变时,我们都要刷新屏幕。这个时候,我们通常需要用到这个函数 repaint(); serviceRepaints(); //强制重绘,慎用!
但是,这样全屏绘制效率很低,在某些手机上效果很不好。所以如果仅需要改变屏幕中一小部分的话,也可以用以下的方法来请求重绘:
Canvas.repaint(int x, int y, int width, int height)
这样你仅需指定屏幕的特定区域,然后用paint方法重绘,效率会提高很多,还会保存计算结果。不过值得注意的是,如果你发了很多次的重绘请求而快于系统的处理速度的话,他就会合并一些处理的请求,并重绘了全屏幕,所以,请尽量不要在循环或者时序较小的定时器中调用repaint(int x,int y,int width,int height)。
有关Motorola J2ME开发的几个细节问题
在实际开发MOTO的产品的时候,会遇到一些细节问题。很烦人,但是往往难到不少人。下面就是我从自己实际开发经历中获得的一些问题的解决。
1. Motorola V系列的J2ME的图标显示
Motorola的V系列手机j2me程序图标大小必须是15*15的大小.而且必须在MIDlet-Icon中填出图标名字.不能只在MIDlet-1中填写.Nokia的手机的确只填写这里就可以了.
2. 存储空间的限制问题
Motorola的手机的RMS存储空间如果不在MIDlet-Data-Size中具体给出,那么默认的就只有8K还是12K,我记不清楚了。所以,必须再MIDlet-Data-Size中给出具体的RMS需要大小。一般MOTO的手机,最大支持64K的RMS空间。
3.Motorola的网络下载问题
在中国卖的MOTO的手机,网络连接点都是默认固定到CMWAP上的。所以,一般的J2ME网络连接的方法,是无法通过CMWAP的网关的。解决的办法有两个。
1)更改手机上的连接点。其实你只要自己随便建立一个新的连接点,什么信息都不用填写,然后将默认的连接点设置在上面,它就可以自动成为CMNET连接点。那么一般的J2ME网络访问方式就可以了。
2)采用CMWAP的连接方式。这个就要求程序上有所改动了。
比如我要下载这样一个数据文件: http://211.136.87.234/1.png
那么其代码方式就是:
c= (HttpConnection)Connector.open("http://10.0.0.172:80/1.png,Connector.READ,true);
c.setRequestProperty("X-Online-Host", "211.136.87.234");
c.setRequestProperty("Accept", "*/*");
is = c.openInputStream();
10.0.0.172是移动的CMWAP网关。
关于J2me的网络问题汇总
1.要关闭多次联网提示,可以购买证书,还有socket连接80/8080端口,也需要安全证书,具体证书的相关信息请在google里面查找即
可。要看哪种手机支持不支持该证书,直接查看根证书即可。
2.HttpConnection.Open的时候尽量不要用三个参数的那个,就是一个url参数,否则有些手机会出问题。
3.不要用getResponseCode,有些手机直接crash.
4.Connector.Open的时是用户弹出网络提示的时候,如果用户决绝访问网络,程序会抛出SecruityException.
5.httpconnection的底层不支持proxy模式,并且host是永远都不可能更改的,除非你用socket,当然也可以修改,必须采用双地址替换方式。
6.如果用户选错接入点,网络进行close的时候会block,会block很长时间,3分钟左右吧,不同手机情况各异。
7.每次读取数据不要超过2k,有些手机堆太小,会直接crash.
8.G网切换到E网的时候,会收到ConnectionReset的异常,无论什么网络异常,用Throwable截获,不要用Exception或者IOException.
NokiaS40和S60开发平台1.0已知问题
1、 Nokia3300不支MMA(声音处理)类库。
2、 Image.getGraphics()方法在不同的软件版本中工作不同,该方法无法在新版本的7650、3650和N-Gage中正常工作。即这些机器中无法实现双缓冲技术。
3、 Nokia7650、3650和N-Gage,无法控制背景灯和震动。
4、 同时播放声音在S60模拟器上可以运行,但是真机不支持。
5、 7650不支持WMA(短信息API)。
6、 在7210SDK1.0中softkey1和softkey2也产生left和right按键代码。
7、 在S60中堆内存不同。一般S60设备有2M,而3600只有1.6M。
8、 记录集枚举问题。在S40SDK和真机中,使用RecordStore.deleteRecord(id)以后,枚举工作不正常。
9、 Nokia6230 MIDP Concept SDK beta0.2不支持CLDC1.1。
10、 NUL字符(0x00)在TextBox中有问题。S401.0 SDK和真机中都存在该问题。
11、 如果MIDlet在后台运行时,MIDI声音不停止。S601.0中存在该问题。
12、 当正在运行的MIDlet被系统Screen隐含调用的类选择显示屏幕时有问题。在S60 1.0中存在该问题。
13、 S40界面风格中的字体大小不一致。在S40 1.0SDK和真机,以及7250i、3100、6108、6200中。
14、 Item.getLable()方法在ChoiceGroup中无法返回正确的label。
15、 在Nokia MIDP 1.0中,DeviceControl.setLights(0,0)没有关闭键区灯。屏幕等关闭,而键区等依然亮着。涉及具有翻页键盘的S40 1.0设备。
16、 在S60 1.0设备中,Date对象无法返回当前时间。
Nokia开发平台2.0(包含S80 2.0、S60 2.0和S40 2.0)已知问题V2.1
本文只涉及Java语言的相关问题,分别如下:
1、 在S40 2.0中的Nokia 6230、Nokia 5140中,使用platformRequest()方法时,必须首先使用notifyDestroyed()方法关闭MIDlet。
2、 在Nokia 6230中,有一个独立设置游戏声音的应用菜单,如果游戏程序安装在游戏集合菜单中,则在游戏程序内部的声音设置无效。
解决办法:提示用户将游戏安装在游戏菜单中。
3、 Nokia 5140中,和MIDP2.0冲突,需要使用“nokiacomm:IRO”,而不是MIDP2.0中定义的“comm:IRO”来连接IRComm。
4、 在Nokia 3220中,配置Internet接入点,可能会导致问题。
5、 在Nokia 6230中,使用HTTPS连接时,设备会为每个连接到同一个服务器的连接,建立一个新的SSL握手,这大大降低了HTTPS连接的性能。
解决办法:使HTTPS连接总是打开,或者减少建立连接的次数。
6、 在S60 2.0平台上,Nokia 6600、Nokia 6620、Nokia 7610中的Display.setCurrentItem()不起作用。
7、 在S60 2.0的Nokia 6600、S60 2.0 FP1的Nokia 6620、Nokia 6260、Nokia 6670、Nokia 7610中,S80 2.0中的Nokia 9300、Nokia 9500中,使用蓝牙序列端口读取流数据时,工作不正常。
8、 在S60 2.0系列的所有设备中,Guage在Alert中作为一个进度条时,不能正常工作。
9、 在Nokia 3220中,播放具有光轨(Light track)的MIDI音乐的时候,对LED没有影响。
10、 在Nokia 3220中,灯光设置工作不正常。——已经在新版本中修复。
11、 在早期的S40 2.0版本的Nokia 6230、Nokia 3220和S60 2.0版本的Nokia 6600中,对于Java校验的根认证丢失。
12、 在Nokia 6630的MMA API无法播放MIDI声音。
13、 在S 60 1.0和2.0版本中,如果你使用deallocate()方法释放资源以后,无法在prefetch方法使播放器进入PREFETCHED状态。
14、 在S 40 2.0设备中,不能使用PIM API添加包含空格字符的电话号码。
十七、在J2ME网络编程中使用CMWAP代理
在中国移动提供的网络连接中,分为CMNET和CMWAP两种,其中CMNET可以无限制的访问互联网络,资费比较贵。CMWAP类似一个HTTP的代码,只能访问支持HTTP的应用,但是资费便宜,稳定性比较差。
在实际的J2ME网络编程中,一般需要提供以CMWAP代理的方式连接网络,在J2ME中,连接的代码和直接连接有所不同,代码如下:
HttpConnection http = (HttpConnection)Connector.open(("http://10.0.0.172/"+url);http.setRequestProperty("X-Online-Host",ServerName);
例如你需要访问的地址为:http://www.test.com/login/loginServlet则上面的代码就为:
HttpConnection http = (HttpConnection)Connector.open(("http://10.0.0.172/" + "login/loginServlet");http.setRequestProperty("X-Online-Host","www.test.com");
在实际使用过程中,只需要使用实际需要访问的地址的域名或者IP来代替ServerName,例如示例中的“www.test.com”,使用后续的地址类代替代码中的url,例如示例中的“login/loginServlet”,就可以实际的使用CMWAP代理来进行连接了。
十九、J2ME中随机数字处理全攻略
在程序中生成随机数字,用处比较,如人工智能领域等等,这里对于在J2ME中生成随机数的操作进行一个简单的整理,希望对大家能有帮助。
J2ME和J2SE不同,不能使用Math类的random来生成随机数字,只能使用java.util包的Random类来生成随机数字。
1、创建Random类型的对象:
Random random = new Random();Random random = new Random(10010010);
以上两种是创建Random对象的方式,第一种使用默认构造方法,和以下的代码作用完全等价:
Random random = new Random(System. currentTimeMillis());
相当与使用当前时间作为种子数字来进行创建。
第二种方式通过自己来指定种子数字来进行创建。
大家可以根据需要使用以上两种方式的任一种。
2、生成随机数字:
创建好了随机对象以后,我们就可以来生成随机数字了:
生成随机整数:
int k = random.nextInt();
生成随机长整数:
long l = random.nextLong();
3、生成指定范围的数字:
例如生成0-10之间的随机数字:
int k = random.nextInt();int j = Math.abs(k % 10);
首先生成一个随机整数k,然后用k和10取余,最后使用Math类的abs方法取绝对值,获得0-10之间的随机数字。
获得0-15之间的随机数,类似:
int k = random.nextInt();int j = Math.abs(k % 15);
获得10-20之间的随机数字:
int k = random.nextInt();int j = Math.abs(k % 10) + 10;
十八、J2ME中的时间处理全攻略
时间处理在程序开发中相当常见,下面对于时间处理做一个简单的说明。
一、时间的表达方式
时间在J2ME中有两种表达方式:
1、以和GMT1970年1月1号午夜12点和现在相差的毫秒数来代表
这种方式适合比较两个时间之间的差值。
2、以对象的形式来表达
二、时间处理的相关类
时间处理在J2ME中涉及三个类:
1、System类
long time = System. currentTimeMillis();
使用该方法可以获得当前时间,时间的表达方式为上面提到的第一种。
2、Date类
Date date = new Date();
获得当前时间,使用对象的形式来进行表达。
3、Calendar类
Calendar calendar = Calendar. getInstance();
三、时间处理的具体操作
1、以上三种表达方式的转换:
a)将System类获得的时间转换为Date对象
Date date = new Date(System. currentTimeMillis());
b)将Date类型的对象转换为Calendar类型的对象
Calendar calendar = Calendar. getInstance();Date date = new Date();calendar.setTime(date);
2、使用Calendar完成一些日期操作:
Calendar是时间处理中最常用也是功能最强大的类,可以用它来获得某个时间的日期、星期几等信息。
获得日期:
Calendar calendar = Calendar. getInstance();……int day = calendar.get(Calendar. DATE);
获得日期、年份、星期的操作和这个类似。
需要注意的是:Calendar中表示月份的数字和实际相差1,即1月用数字0表示,2月用数字1表示,……12月用数字11表示。
----------------机型相关问题-----------------
1 Nokia S60 IO操作内存泄漏不可不察
Nokia7650,3650
游戏运行过程中,有时会出现“存储已满”的对话框,出现的位置不固定
游戏运行过程中,有时出现“应用程序错误 NullPointerExcept”,“程序已关闭 MidpUi”的对话框
游戏运行过程中,有时会出现“程序已关闭 MidpUi ViewSrv 9”的对话框,出现的位置不固定
其实这个问题是由S60的getResourceAsStream方法内存泄漏的bug引起的,由于每次切换地图时io操作都要读取大量数据,内存泄漏积累到一定程度就引起了“存储已满”,白屏,死机,进而会引起null pointer异常等。解决方法是尽量减少io操作的次数。如果内存够大就一次将资源读入。
5 Nokia"不能运行应用程序"错误新解
Nokia手机运行J2ME程序的时候出现“不能运行应用程序”的错误,一般都是内存不足引起的,但今天遇到这样的错误,却发现是另一个原因。即当使用nokia的UI API,DirectGraphics的drawImage时,如果旋转参数设置不当,也会出现“不能运行应用程序”的错误。
6 Nokia系统bug两则
(1) Nokia7650(V4.46)应用程序目录显示bug
应用程序安装后,打开应用程序目录,显示错误提示:
"程序已关闭 MidpUi USER9",应用程序目录无法进入。
分析后发现,原来是新安装的应用程序没有在mainfest.mf中的
midlet-1属性中指定应用程序图标,导致程序目录无法显示图标。
在我所见到NokiaS40机器上和NGageQD上,如果图标没指定或指定了但
不存在,将显示默认的图标。
此bug对于其它版本的7650或者其他机型是否存在尚不得知。
解决方法:使用seleQ将7650c:/system/midp中刚安装的程序目录删掉,即可正常进入应用程序目录。
在应用中使用自己的应用程序图标,并正确设置,以避免让用户遭遇到此bug。
Motorola手机J2ME应用问题
(1) 应用程序图标
必须在jad 文件Midlet-Icon属性中指定图标文件,Midlet-1中指定的图标无效
Moto V系列图标大小应为15*15,其他尺寸无法显示。
(2) 左右软键问题
Motorola手机操作系统设定是:右软键确认,左软键取消。所以,我们的程序应该和这个习惯保持一致。
(3) Key Code
Moto V的key code不同于其他Midp2.0机器
左软键:21
右软键: 22
中键: 20
up: 1
down: 6
left: 2
right: 5
2. 存储空间的限制问题
motorola的手机的rms存储空间如果不在midlet-data-size中具体给出,那么默认的就只有8k还是12k,我记不清楚了。所以,必须再midlet-data-size中给出具体的rms需要大小。一般moto的手机,最大支持64k的rms空间。
多机型移植经验谈
1。各机型之间最大的差别就是屏幕大小不同。所以游戏中要能自适应屏幕大小
J2ME写了有段时间了,就我自己掌握的一点机型适配经验和大家分享下:
1. Canvas类的getHeight(),getWidth() 问题
这两个方法在很多MOTO和三星手机上 都不能及时返回屏幕的高度和宽度,返回的数据可能不是真正的屏幕高度和宽度,从而导致画面显示的混乱。
【解决方案】:通常是用一个静态变量保存屏幕高度和宽度,在闪屏进入时获取一次屏幕高度和宽度赋给变量,然后在线程里休眠一段时间,在线程结束时再获取一次赋值给变量,后面的所有画面就引用这个静态变量的值,不要再用及时获取getHeight(),getWidth() 值;
2. jad文件问题导致软件安装失败
在有的MOTO手机上安装软件,会发生软件错误,从而导致安装失败。抛开软件本身BUG的问题,其实还有一个地方也是导致安装失败的原因,就是在打包时,你的jad文件.
例如这个jad文件有可能就会导致安装失败:
MIDlet-Jar-URL: XXBook.jar
MIDlet-Name: 潇湘书院-官方版
MIDlet-Vendor: 上海世秋
MIDlet-Version: 1.0.0
MicroEdition-Configuration: CLDC-1.0
MicroEdition-Profile: MIDP-2.0
MIDlet-1: 潇湘书院,/icon.png,GameMIDlet
就是MIDlet-Vendor这里,后面的中文名可能导致安装失败
【解决方案】:MIDlet-Vendor:后面最好是英文的公司信息,其他项中文问题暂未发现。
3. 图片显示不了
在有的MOTO和三星手机上莫名其妙的显示不了图片,这个问题其实也是手机支持的问题,有的手机不支持图片alpha的显示,也就是有透明度的图片显示。
【解决方案】:将图片换成不透明的图片
暂时发现这么多,以后有的话再补充。
本文csdn原创,转载请注明出处。谢谢!
本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/cool_ping/archive/2010/01/07/5145007.aspx
* 错误:
Nokia S60游戏运行了比较长一段时间后,无法绘制图片或者抛出OutOfMemoryError,游戏崩溃。
* 可能的原因:
Nokia S60对J2ME的垃圾回收支持不行,它的drawRegion()(MIDP2.0)方法,产生的图片不会被很好的回收,会不停的消耗内存,导致内存溢出,游戏崩溃。
* 和标准J2ME SDK 不同
S60 的sdk不支持String.equalsIgnoreCase()方法。
* 错误
[Loaded com/ltt/gknight/Gknight]
[Loaded com/ltt/gknight/GknightCanvas]
java.lang.Error: Static initializer: java.lang.NullPointerException, null
- java.lang.Class.throwError(), bci=57
- java.lang.Class.initialize(), bci=221
- java.lang.Class.forName(), bci=0
- com.symbian.midp.runtime.MIDletExecutor$MIDletConstructorThread.run(), bci=43
Uncaught exception: java.lang.RuntimeException: java.lang.Error: Static initializer: java.lang.NullPointerException, null
- com.symbian.midp.runtime.MIDletExecutor$MIDletConstructorThread.run(), bci=183
* 可能的原因
在MIDlet定义static的Form对象的同时实例化对象,例如,
public class Gknight extends MIDlet {
public static Display display = null;
public static GknightCanvas canvas = null;
public Form frm = new Form("P");
public Gknight(){
display = Display.getDisplay(this);
canvas = new GknightCanvas(this,display);
}
protected void startApp() throws MIDletStateChangeException {
if( canvas != null ){
display.setCurrent(canvas);
}
}
protected void pauseApp() {
}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
}
}
用于J2ME的批处理工具jaz.bat
将class目录下的文件打包,参照当前目录下的manifest。
@echo off
rem
rem generate %1.jar file from
rem ./MANIFEST.MF, ./class
rem
set CLSDIR="./class"
if EXIST %1.jar del /Q %1.jar
jar cmf MANIFEST.MF %1.jar -C %CLSDIR% .
echo Done!
nokia 6681的内存较小,且KVM功能有欠缺,内存管理能力不足。http://blog.youkuaiyun.com/c30gcrk/archive/2007/10/11/1820488.aspx
诺基亚智能手机常见问题 http://blog.youkuaiyun.com/c30gcrk/archive/2008/04/05/2252669.aspx