1. java.lang.IllegalArgumentException:
    at Canvas3.paint(+11)
    at javax.microedition.lcdui.Canvas.callPaint(+85)
    at javax.microedition.lcdui.Display.repaint(+82)
    at javax.microedition.lcdui.Display$DisplayAccessor.repaint(+14)
    at javax.microedition.lcdui.Display$DisplayManagerImpl.repaint(+16)
    at com.sun.midp.lcdui.DefaultEventHandler.repaintScreenEvent(+24)
    at com.sun.midp.lcdui.DefaultEventHandler$QueuedEventHandler.run(+485)

g.drawImage(i, 0, 0, Graphics.LEFT);

改成g.drawImage(i, 0, 0, Graphics.LEFT Graphics.TOP);
Left=4,top=16.Left top=20,可能是因为这个anchor参数不合法吧。太大太小都不行的。。

2.java.lang.SecurityException: Application not authorized to access the restricted API
at com.sun.midp.security.SecurityToken.checkIfPermissionAllowed(+40)
at com.sun.midp.security.SecurityToken.checkIfPermissionAllowed(+7)
at com.sun.midp.midletsuite.MIDletSuiteImpl.checkIfPermissionAllowed(+8)
at com.sun.midp.midlet.MIDletState.(+83) at javax.microedition.midlet.MIDletProxy.(+5) at javax.microedition.midlet.MIDlet.(+13) at LrcAnalyst.(+4) at TestLrc.startApp(+15) at javax.microedition.midlet.MIDletProxy.startApp(+7) at com.sun.midp.midlet.Scheduler.schedule(+270) at com.sun.midp.main.Main.runLocalClass(+28) at com.sun.midp.main.Main.main(+116)

说什么安全性异常,这是因为把对象定义成局部变量了,我把它的new 放到全局变量,就ok了。

3.Method…………: 257f640 ‘TestLrc.startApp (virtual)’
Stack Chunk…….: 2390300
Frame Pointer…..: 23903a8
Current IP……..: 257f5bf = 257f5ac + offset 19
Previous Frame….: 2390388
Previous IP…….: 10324375 (offset 7)
Frame size……..: 2 (1 arguments, 1 local variables)
Argument[0]…….: 257efcc
Local[1]……….: 257e7a0
Operand[1]……..: 257e7a0
Operand[2]……..: 257f6a4

Method…………: 1021ecac ‘javax/microedition/midlet/MIDletProxy.startApp (virtual)’
Stack Chunk…….: 2390300
Frame Pointer…..: 2390388
Current IP……..: 10324375 = 1032436e + offset 7
Previous Frame….: 239036c
Previous IP…….: 1038a23e (offset 270)
Frame size……..: 1 (1 arguments, 0 local variables)
Argument[0]…….: 257ef90

Method…………: 10263264 ‘com/sun/midp/midlet/Scheduler.schedule (virtual)’
Stack Chunk…….: 2390300
Frame Pointer…..: 239036c
Current IP……..: 1038a23e = 1038a130 + offset 270
Previous Frame….: 2390338
Previous IP…….: 103750f1 (offset 28)
Frame size……..: 7 (2 arguments, 5 local variables)
Argument[0]…….: 238fe40
Argument[1]…….: 2381f14
Local[2]……….: 257ef90
Local[3]……….: 2
Local[4]……….: 238fe34
Local[5]……….: 257f4c4
Local[6]……….: 10263184

Method…………: 10257600 ‘com/sun/midp/main/Main.runLocalClass (static)’
Stack Chunk…….: 2390300
Frame Pointer…..: 2390338
Current IP……..: 103750f1 = 103750d5 + offset 28
Previous Frame….: 2390314
Previous IP…….: 10374b38 (offset 116)
Frame size……..: 3 (1 arguments, 2 local variables)
Argument[0]…….: 23900a4
Local[1]……….: 2381f14
Local[2]……….: 257f48c

Method…………: 10257560 ‘com/sun/midp/main/Main.main (static)’
Stack Chunk…….: 2390300
Frame Pointer…..: 2390314
Current IP……..: 10374b38 = 10374ac4 + offset 116
Previous Frame….: 0
Previous IP…….: 1
Frame size……..: 3 (1 arguments, 2 local variables)
Argument[0]…….: 23905f0
Local[1]……….: 23900a4
Local[2]……….: 238d9a4

VM status:
Instruction pointer.: 257f5bf (offset within invoking method: 19)
Next instruction….: 0xb6
Frame pointer…….: 23903a8
Local pointer…….: 23903a0
Stack size……….: 256; sp: 23903c4; ranges: 2390308-2390508;257ecb0-257eeb0;
Contents of the current stack frame:
    23903a0: 257efcc (lp)
    23903a4: 257e7a0
    23903a8: 2390388 (fp)
    23903ac: 10324375
    23903b0: 239039c
    23903b4: 257f640
    23903b8: 2390300
    23903bc: 0 (end of frame)
    23903c0: 257e7a0
    23903c4: 257f6a4 (sp)
Execution stack contains 192 items:
23905f0
23900a4
238d9a4
0
1
257f47c
10257560
2390300
0
23900a4
2381f14
257f48c
2390314
10374b38
2390328
10257600
2390300
0
238fe40
2381f14
257ef90
2
238fe34
257f4c4
10263184
2390338
103750f1
239034c
10263264
2390300
0
257ef90
239036c
1038a23e
2390380
1021ecac
2390300
0
257efcc
257e7a0
2390388
10324375
239039c
257f640
2390300
0
257e7a0
257f6a4

Execution completed.
3417736 bytecodes executed
273 thread switches
1647 classes in the system (including system classes)
17730 dynamic objects allocated (528660 bytes)
2 garbage collections (458296 bytes collected)
Execution completed.
3417736 bytecodes executed
273 thread switches
1647 classes in the system (including system classes)
17730 dynamic objects allocated (528660 bytes)
2 garbage collections (458296 bytes collected)
ALERT: java/lang/NoSuchMethodError: No such method showLrc.(Ljava/lang/String;)V.

这个异常太搞笑了,so long….

关于Midlet

J2ME编程过程中,MIDlet是最核心的类之一,熟悉该类的使用是J2ME学习过程中必须首先掌握的类,下面就结合实际介绍一下该类的实际使用。

J2ME编程过程中,MIDlet是最核心的类之一,熟悉该类的使用是J2ME学习过程中必须首先掌握的类,下面就结合实际介绍一下该类的实际使用。

众所周知,J2ME程序都是从MIDlet类开始执行,系统规定了MIDlet的生命周期。规定MIDlet程序有三种状态:

1、 暂停状态

2、 运行状态

3、 销毁状态

系统在执行MIDlet程序时,首先构造一个MIDlet类型的对象,然后使程序进入到暂停状态,按照生命周期的规定,系统会自动调用MIDlet对象的startApp方法使程序进入到运行状态,开始程序的执行。如果在创建MIDlet对象的过程中,或者是调用startApp的方法中发生了异常,则系统会自动调用MIDlet对象的destroyApp方法进行到销毁状态,也就是使程序退出

所以生命周期中的第一个需要注意的地方就是熟悉在以上状态转换过程中,系统会自动调用的方法,然后在实际编写MIDlet类的时候,在这些方法中书写合适的代码,这样就可以在系统规定的状态转换时,自动调用这些方法

另外一个需要说明的状态是暂停状态,系统在程序运行过程中,如果手机有来电,则系统会自动的使MIDlet程序进行到暂停状态,在进入到暂停状态以前,系统会自动调用MIDlet对象的pauseApp方法。当电话接听完毕以后,系统会自动使MIDlet程序进行到运行状态,在进入到运行状态以前,系统还会自动调用startApp方法使系统进入到运行状态。

对于上面的内容做一个简单的总结:

1、 startApp方法

在系统第一次运行的时候,系统会自动调用该方法使系统进入到运行状态。

当系统从暂停状态切换到运行状态以前,系统也会自动调用该方法

2、 pauseApp方法

当系统从运行状态切换到暂停状态以前,会自动调用该方法

3、 destroyApp方法

当系统发生异常退出程序以前,会自动调用该方法。该方法有一个boolean类型的参数,如果该参数为true则代表该方法必须清理和释放资源,如果为false可以抛出一个MIDletStateChangeException异常来表明它不想立即退出

熟悉了这几个方法的使用以后,可以实现很多实用的功能,下面介绍两个实际功能的实现:

1、 实现来电话时暂停的功能

在实际的MIDlet编程中,必须实现手机来电时暂停程序的功能,如果有线程时,还需要把线程停止掉,然后当电话结束以后,重新显示界面,并重新启动线程。

startApp方法的具体的实现代码框架如下:

public void startApp(){

//获得当前显示的界面

Displayable curr = display.getCurrent();

//判断是否是第一次运行

if(curr == null){

//显示第一个界面,例如logo界面

}else{

//显示来电以前的界面

display.setCurrent(curr);

//如果需要,还可以启动线程

}

}

如果游戏界面中有线程,则需要在来电时暂停线程,而pauseApp在暂停以前会被系统调用,所以可以在pauseApp方法中实现该功能。pauseApp方法的实现代码框架如下:

public void pauseApp(){

//获得当前显示的界面

Displayable curr = display.getCurrent();

//判断是否是游戏界面

if(curr instanceof GameCanvas){

//停止线程

}

}

2、 实现按挂机时清理的功能

熟悉MIDlet编程的人都知道,在程序运行过程中按挂机键,可以使MIDlet程序退出,在低级用户界面编程中,可以在keyPressed方法中捕获该事件,但是却无法处理,因为捕获以后,程序就直接退出了。

如果游戏中有背景音乐等,则当按挂机键直接退出的时候,音乐还会存在,这样就会造成很多的问题。但是按挂机键以后,在程序退出以前,系统会自动调用destroyApp方法,所以可以把最后处理的代码放置在destroyApp方法中。

下面接着来看一下另一组方法,来继续熟悉MIDlet类的使用:

1、 notifyPaused

使程序进入暂停状态

2、 notifyDestroyed

程序进入到销毁状态。

以上两个方法和上面的三个方法不同,上面的三个方法是在状态切换过程中,会自动被系统调用。而这两个方法不会被系统自动调用,但是程序员在实际编程过程中可以手动调用这两个方法,使程序进入指定的状态。

比如如果想实现程序退出的功能,就只需要使MIDlet程序进入到销毁状态即可,也就是只需要手动调用notifyDestroyed方法即可。

上面是MIDlet类中最主要的两组方法,下面分MIDP1.0和MIDP2.0来分别介绍剩下的方法的作用。首先看一下MIDP1.0中的两个方法

1、 getAppProperty

获得jad文件和manifest文件中属性的值,如果一个属性在以上两个文件中都包含,则以jad文件中的属性值为准。

2、 resumeRequest

系统通过调用该软件来判断是否需要使该MIDlet进入运行状态。如果需要进入运行状态,则系统会自动调用startApp方法

在MIDP2.0中,MIDlet类中新增了两个方法,下面介绍一下这两个方法的作用,依次是:

1、 checkPermission

方法是MIDP2.0的安全许可机制,在程序的实际使用过程中,可以通过该方法来检查MIDlet是否允许特定的操作,例如联网、发送短信息等等。

如果不允许该操作则返回0,允许返回1,未定义则返回-1。

2、 platformRequest

使用该方法可以访问某些系统功能,例如通用的功能主要有两种

使系统打开浏览器访问某个特定的网址:

platformRequest(“http://wap.sina.com.cn”);

这个功能可以实现用来实现提示用户下载新的程序版本等功能。

使手机拨打特定的电话号码:

paltformRequest(“tel:1860”);

则系统会自动利用手机来拨打1860

*在一个canvas的子类里面打算退出程序,开始用System。exit();结果出现异常。用midlet。notifyDestroyed()就可以了。