J2ME游戏死机问题

学习j2me,首先要了解MIDlet的生命周期。本文主要是深入了解一下MIDlet的生命周期。以上自己的个人心得,不对之处,希望大家多多指点。
    首先在你运行一个程序的时候,
JAM会调用该midlet的构造函数来生成midlet的对象,然后被jam置于Paused状态。一旦jam认为这个midlet对象可以执行时,jam就会调用startApp()方法,并将此midlet置于Active状态。startApp()方法由于在系统来电、或者退回到系统菜单返回时会被再次调用,所以这里只可以放初始化一次的代码。或者你把初始化一次的代码放到midlet的构造函数中。例如:
public class Midlet extends MIDlet{
  Display display = null;
  MyCanvas can;
 
  public Midelt(){
 
      display = Display.getDisplay(this);
 
      can = new MyCanvas();
 
}
 
  public void startApp(){
 
     display.setCurrent(can);//如果把can = new MyCanvas()放到这里,再来电返回时就会出问题。
 
 
}
 
}
 
或者
 
 
public class Midlet extends MIDlet{
 
  Display display = null;
 
  MyCanvas can;
 
  public Midelt(){
 
}
 
  public void startApp(){
 
      if(display ==null){
 
       display = Display.getDisplay(this);
 
       can = new MyCanvas();
 
}//此处只会被运行1次,这样就不会出错
 
 
       display.setCurrent(can);//这句按理放到这里最合适,你想显示那个canvas就放哪个!
 
 
}
 
}
 
 
在startApp()中,你调用display.setCurrent(can)的时候,首先运行的是showNotify(),接着运行paint()函数一次,如果有线程的话,此时run()方法开始运行。一般在run()方法里一般这么写。此时的run()是可以处理异步事件的,也就是你来电话的时候,这里run()还是运行的。不过他不会paint()什么东西,即使它里面有repaint(),这点放心。
 
 
 public void run(){
 
while(flag){//flag是boolean型变量
 
 
try{
 
  Thread.sleep(50);//时间自己设啦。
 
 
}catch(Exception e){}
 
repaint();
 
}
 
}
 
 
哇~~来电话了,或者你退到系统菜单。如nokia s60的手机。
 
 
hideNotify()首先会被调用,接着pauseApp()再被调用。
 
 
 
这么快,打完了,返回时:先调用showNotify(),接着调用paint()函数一次,最后才是调用startApp()函数。
 
 
关于run()和paint()也可以使用display.callSerially(this)语句。这个以后有时间了再说。
明白了生命周期,再来看死机问题。我说的死机问题,多是来电话返回时死机。其实只要找到了问题,一切就变的很简单。
 
为什么死机,归根结底还是程序问题。好像是废话。哈~~
 
Graphics mg;//定义的全局参数
 
 
paint(Graphics g){
 
mg = g;//有的程序这样写,if(mg ==null){mg =g:}这样对于n7610系列就会出错。
 
mg.drawString();
 
switch(case){
 
   case GAME_MUNE:
 
       drawA();
 
   break;
 
 
   case PLAY:
 
        drawB();
 
   break;
 
       default:
 
       break;
 
}
 
}
 
/*下面的画图函数一定要放到paint()函数里调用,不要在别的地方调用,如run()里面,上面说过,程序暂停之后返回,会先paint()一次,如果在别的地方调用就会出现问题。*/
 
public void drawA(){
 
mg.drawString();
 
}
 
public void drawB(){
 
mg.drawString();
 
}
 
按照上面的写法一般不会出现死机问题。当然,你也可以不定义全局的mg,可以把g单独传到各个画图子函数中。如,
 
paint(Graphics g){
 
g.drawString();
 
switch(case){
 
   case GAME_MUNE:
 
       drawA(g);
 
   break;
 
 
   case PLAY:
 
        drawB(g);
 
   break;
 
       default:
 
       break;
 
}
 
}
 
public void drawA(Graphics mg){
 
mg.drawString();
}
public void drawB(Graphics mg){
mg.drawString();
}