对于MIDP应用程序来说,由于手机设备上的资源非常有限,较弱的CPU计算能力,有限的内存(从几十KB到几百KB,虽然少数高端手机拥有超过 1M的动态内存),很小的屏幕尺寸,因此,为了让一个MIDP应用程序能够不加改动地在多种不同手机上运行,程序必须有能力根据系统配置自动调整运行时的参数。比如,对于内存非常小的手机,如果从网络下载一幅较大的图像,需要分配巨大的缓冲区,就可能导致OutOfMemoryError错误,使应用程序直接终止,这会使用户感到不知所措,或者丢失用户的重要数据。
因此,在试图分配一块大内存之前,首先使用System.gc()尝试让垃圾收集器释放无用对象占用的内存,然后,使用Runtime.getRuntime().freeMemory()方法获得可用的内存空间。如果可用空间太小,给用户一个“内存不足,无法完成操作”的Alert提示,从而尽可能地避免OutOfMemoryError错误。
System.gc();
int max_size = 102400; // 100KB
int free_size = (int)Runtime.getRuntime().freeMemory();
if(max_size>free_size*2/3) {
// TODO: Alert!
}
else {
byte[] buffer = new byte[max_size];
// TODO: Download image...
}
-减少图片以减小JAR文件大小-
许多手机会因为JAR文件太大而无法运行MIDP应用程序,而减小JAR文件尺寸的有效方法之一是减少不必要的图片,例如,启动时的 LOGO图片可以用文字来代替,列表项可以只显示文字而不显示图片。为了能适应不同配置的手机,我们的代码就应该编写得更加灵活。例如,从JAR包中加载图片时:
Image image = null;
try {
image = Image.createImage("/logo.png");
}
catch(Exception ioe) {}
if(image==null) {
g.setColor(0);
g.drawString("info", getWidth()/2, getHeight()/2, Graphics.HCENTER|Graphics.BASELINE);
}
else {
g.drawImage(image, getWidth()/2, getHeight()/2, Graphics.HCENTER|Graphics.VCENTER);
}
如果加载失败,程序会以文字方式显示,这样,对于低配置的手机,只需要把美化界面的图片删除掉,再重新打包即可得到一个可发布的尺寸较小的JAR包,同时应用程序的代码并没有改动。
类似的,在加载List之类的UI组件时:
Image image = null;
try {
image = Image.createImage("/logo.png");
}
catch(Exception ioe) {}
append("label", image);
这使得有无图片仅仅影响界面美观,而不影响应用程序的功能。
-获取设备支持的可选API-
J2ME规范包括了许多可选包,如支持多媒体功能的MMAPI,支持消息接收和发送的WMA,支持3D游戏的M3G API。如果某一款手机支持某个可选API,MIDP应用程序就可以使用它。但是,让用户回答“本机是否支持MMAPI”是不友好的,发布几个不同版本不但增加了开发的工作量,也让用户难以选择。因此,应用程序应该自己检测手机是否支持某一API,从而在运行期决定是否可以使用此API。
MIDP 1.0和2.0应用程序都可以通过System.getProperty(String key)检测某一个属性的信息。如果该属性有效,将返回对应的字符串,否则,返回null,表示系统不支持此功能。
例如,System.getProperty("microedition.profiles")可能的返回值是"MIDP-1.0"或"MIDP-2.0"。
以下是常见的系统属性和可选API的属性,右侧列出了可能的返回值:
系统信息
microedition.platform 平台名称,如j2me
microedition.configuration CLDC或CDC版本,如CLDC-1.0
microedition.profiles MIDP版本,如MIDP-1.0
microedition.encoding 默认的系统编码,如GBK
microedition.locale 默认的区域设置,如zh-CN
MMAPI相关
microedition.media.version MMAPI的版本,如1.1
supports.mixing 是否支持混音,如true
supports.audio.capture 是否支持音频捕获,如true
supports.video.capture 是否支持视频捕获,如true
supports.recording 是否支持录音,如true
audio.encodings 音频编码格式,如encoding=pcm encoding=pcm&rate=8000&bits=8&channels=1
video.snapshot.encodings 拍摄图片的编码格式,如encoding=jpeg encoding=png
streamable.contents 支持的流媒体格式,如audio/x-wav
WMA相关
wireless.messaging.sms.smsc 返回SMS的服务中心,如+8613800010000
wireless.messaging.mms.mmsc 返回MMS的服务中心,如http://mmsc.monternet.com
其他
microedition.m3g.version 返回Mobile 3D的版本,如1.0
bluetooth.api.version 返回蓝牙API的版本,如1.0
microedition.io.file.FileConnection.version 返回FileConnection的版本,如1.0
microedition.pim.version 返回PIM的版本,如1.0
例如,如果用户的手机内置了数码相机,并且支持MMAPI,我们就可以在MIDP程序中拍摄照片。因此,在应用程序启动时就应该判断是否启用拍照功能以及用户手机支持的图片编码格式:
boolean supports_take_photo = false;
boolean supports_jpeg_encoding = false;
boolean supports_png_encoding = false;
boolean supports_gif_encoding = false;
if(System.getProperty("microedition.media.version")!=null) {
if("true".equals(System.getProperty("supports.video.capture")))
supports_take_photo = true;
String all_encoding = System.getProperty("video.snapshot.encodings");
if(all_encoding!=null) {
if(all_encoding.indexOf("jpeg")!=(-1))
supports_jpeg_encoding = true;
if(all_encoding.indexOf("png")!=(-1))
supports_png_encoding = true;
if(all_encoding.indexOf("gif")!=(-1))
supports_gif_encoding = true;
}
}
}
NOKIA 6260 无法开启摄像头
应该是 cldc 1.0导致的问题。