曾经参加过一次J2ME项目的开发,把学习到的一点点心得记在这里,以利查阅。
验证一个class文件时遇到错误:
Class loading error: Illegal constant pool index
JDK版本:1.4.2
MIDP版本:1.0.3
解决方法:在编译class时,加入参数:-target 1.1
如果描述文件或清单文件之中出现了非ASCII编码定义的文字,就一定要以ASCII编码的Unicode 形式出现才可以(不是UTF8),否則会出现问题。
Jar内部要有一个清单文件(Manifest.mf),外部要有一个描述文件(.jad),其MIME类型为"text/vnd.sub.j2me.app-descriptor"。
清单文件至少包含以下属性项:
MIDlet-Name
MIDlet-Version
MIDlet-Vendor
MIDlet-<n> (每一個屬於此MIDlet Suite 的MIDlet 都該有一個)
MicroEdition-Profile
MicroEdition-Configuration
描述文件至少包含一下属性项:(所有属性必须以MIDlet开头)
MIDlet-Name
MIDlet-Version
MIDlet-Vendor
MIDlet-Jar-URL
MIDlet-JAR-Size
如果以上两个文件中属性值发生冲突,以描述文件(.jad)为主。
javax.microedition.midlet.MIDlet 类中定义了三个抽象方法:
startApp()
pauseApp()
destroyApp()
我们编写的任何手机MIDlet必须继承自这个类,并且需要实现这三个方法。
任何从paused状态变为activity状态,都要调用startApp()方法,因此,只需要被初始化一次的参数不应该写在startApp()方法中,应写在这个类的构建器(construector)方法中。
在MIDlet中不应该有public static void main(String[] args)方法,即使有,JAM也会忽略。
Java的命令行编译命令支持自动联编。比如A类中引用了B类,编译A时,编译器会自动编译B。前提是B类要在当前的classpath路径中,并且以B.java命名。
MIDP中的验证工具Preverify.exe具有以上类似的功能。
MIDlet 自身没有改变自己状态的能力,需要调用相关方法,由JAM代劳。需要注意的是:上述提到的三个方法,并不能控制MIDlet生命周期,MIDlet自身调用这些方法,仅仅是执行了这些方法中的代码而已,并没有改变MIDlet自身的状态。必须额外调用其他三个方法:
notifyPaused() //change to pause state
resumeRequest() //change to activity state
notifyDestroyed() //destroy MIDlet
一个最简的MIDlet程序如下:
//------------------------------------------------------
import javax.microedition.midlet.*;
publlic class HelloMIDlet extends MIDlet
{
public HelloMIDlet()
{
// 构建器
}
public void startApp()
{
}
public void pauseApp()
{
}
public void destroyApp(boolean unconditional)
{
}
}
//------------------------------------------------------
启动应用的一般步骤:
startApp()
-> 进入运行状态
-> 取得代表屏幕的Display对象: Display.getDisplay(this)
-> 设置显示画面: Display.setCurrent(Displayable 类的实例)
一个可以显示画面的最简MIDlet程序如下:
//------------------------------------------------------
import javax.microedition.midlet.*;
publlic class HelloMIDlet extends MIDlet
{
private Display display;
public HelloMIDlet()
{
//... ...
display = Display.getDisplay(this);
//... ...
}
public void startApp()
{
//... ...
TextBox t = new TextBox(... ...);
display.setCurrent(t);
//... ...
}
public void pauseApp()
{
}
public void destroyApp(boolean unconditional)
{
}
}
//------------------------------------------------------
MIDlet的事件处理,共有四类
- 高级事件处理: 由程序触发
- 低级事件处理: 当手机按钮或触摸屏被触摸时触发
- 绘图事件处理
- Display类
MIDP1.0中,所有可视类都是由Displayable这个抽象类派生。由Displayable 派生出了Screen类和Canvas类。
Screen类主要用来处理高级事件,Canvas类用来处理低级事件。
高级事件处理实际上是向屏幕上的可视类注册了一组选项和对应的处理方法,可视类捕获到相应的事件便会触发由你自己实现的事件处理方法。
高级事件处理简单,但不够灵活。
低级事件处理的一些比较重要的事件:
KeyPressed()
KeyReleased()
KeyRepeated() 按住某个键不放产生连续事件,只有部分手机支持,使用hasRepeatEvents()判断。
在MIDP1.0 中定义了一些常数:KEY_NUM0 ~ KEY_NUM9, KEY_STAR, KEY_POUND。分别对应0 - 9数字键,*和#键。
其它与游戏键盘代码相关的常数:UP, DOWN, LEFT, RIGHT, FIRE, GAME_A ~ GAME_D。使用Canvas提供的方法getGameAction()与getKeyCode(),在键盘代码与KeyCode之间进行提取。
pointerPressed() 传入触摸笔点选位置的坐标
pointerReleased() 传入触摸笔离开位置的坐标
pointerDragged() 传入触摸笔拖拽时所在位置的坐标
hasPointerEvents() 判断手机是否支持触摸笔事件
hasPointerMotionEvents() 判断是否支持拖拽事件


