本文共 4493 字,大约阅读时间需要 14 分钟。
在midlet编程中,很多系统的属性要通过一个midlet实例来访问,比如display.getdisplay,那么在需要切换界面的类里面你必须把midlet实例或者display实例传送给他,尤其在设计弹出和可以返回的界面时。没有更好的办法吗?又比如程序的暂停功能,有没有根方便的方法把他们集成起来?还有错误处理,程序退出等等,利用以往的方法是不是很不爽? 嗯,真是不爽,于是我写了这个程序管理器:app。首先看他的组织方式:
static app instance;display disp_;midlet app_;public static void createinstance(midlet app){ if(instance==null) instance=new app(); instance.app_=app; instance.disp_=display.getdisplay(app);}private app(){} |
每个midlet只需要一个管理器,所以只允许一个实例。这样,我们就可以通过静态方法提供一些系统参数的访问方法:
public static string getproperty(string name){ return instance.app_.getappproperty(name);}public static display getdisplay(){ return instance.disp_;} |
他还应该提供返回前一屏的功能,如何实现呢?既然有了display,难道每次还是要app.getdisplay().setcurrent(xxx)?索性提供一个app.setcurrent():
public static void setcurrent(displayable d){ if(d!=instance.old_) { instance.old_=instance.disp_.getcurrent(); instance.disp_.setcurrent(d); }} |
对了,我们就利用这个来实现切换到前一屏的功能:
public static void restore(){ if(instance.old_!=null) { instance.disp_.setcurrent(instance.old_); instance.old_=null; }} |
接下去该轮到程序暂停和恢复的处理以及一些常用命令
public static boolean restart(){ if(instance.paused_) { instance.disp_.setcurrent(instance.bef_); instance.paused_=false; return true; } else return false;}public static void pause(){ instance.bef_=instance.disp_.getcurrent(); instance.paused_=true;}public static void exit(){ instance.app_.notifydestroyed();}public static void handleerror(string msg, exception ex){ system.out.println(msg+"::"+ex);} |
下面讲述多语言支持的集成。语言选择当然需要一个界面,就是这个:
class languagemenu extends list implements commandlistener{ command cmdok_; object[] langlist_=new object[]{ "chinese","zh_cn",null, "usa","en_us",null}; public languagemenu() { super("select language",list.implicit); for(int i=0;i { this.append((string)langlist_[i],(image)langlist_[i+2]); } cmdok_=new command("ok",command.screen,2); this.addcommand(cmdok_); this.setselectcommand(cmdok_); this.setcommandlistener(this); } public void commandaction(command c, displayable d) { if(c==cmdok_) { ...... } }} |
这个时候又碰到了一个在实现snprotector的时候碰到的问题,如何中断程序然后在用户确认后继续执行?在制作snprotector的时候采用了pause-resume的方法实现了功能,但是效果不太理想。那只好自己多写些代码避免用户的麻烦。
这个方法通过引入一个iapp的接口,midlet类要实现这个接口:
public interface iapp{ public void start();} |
然后把原来在startapp的内容放入start之中。在app中增加一个方法:
static void continuerun(){ if(instance.app_ instanceof iapp) { ((iapp)instance.app_).start(); }} |
好了,然后该具体实现一下语言选择菜单了:
class languagemenu extends list implements commandlistener{ command cmdok_; object[] langlist_=new object[]{ "chinese","zh_cn",null, "usa","en_us",null }; public languagemenu() { super("select language",list.implicit); for(int i=0;i { this.append((string)langlist_[i],(image)langlist_[i+2]); } cmdok_=new command("ok",command.screen,2); this.addcommand(cmdok_); this.setselectcommand(cmdok_); this.setcommandlistener(this); } public void commandaction(command c, displayable d) { if(c==cmdok_) { int cmd=this.getselectedindex(); instance.lang_=(string)langlist_[cmd*3+1]; try { recordstore.deleterecordstore(languagerms); } catch(exception ex) {} try { recordstore rs=recordstore.openrecordstore(languagerms,true); byte[] buf=instance.lang_.getbytes(); rs.addrecord(buf,0,buf.length); rs.closerecordstore(); } catch(exception ex) {} continuerun(); } }} |
同样通过rms保存了用户的选项,不用每次都选择,最后当然需要有个函数对这些工作进行调度:
public static boolean selectlanguage(){ boolean r=(instance.lang_!=null); if(!r) { try { recordstore rs=recordstore.openrecordstore(languagerms,true); recordenumeration e=rs.enumeraterecords(null,null,false); if(e.hasnextelement()) { instance.lang_=new string(e.nextrecord()); r=true; } else { r=false; } rs.closerecordstore(); } catch(exception ex) { r=false; } if(!r) { app.setcurrent(instance.new languagemenu()); } } return r;} |
程序管理器写完了,那么如何把他整合进midlet里面?看一下几个主要的函数就清楚了:
public testsm(){ app.createinstance(this);}protected void startapp() throws midletstatechangeexception { if(app.selectlanguage() && !app.restart()) { start(); }}public void start(){ sm.getinstance(app.getlanguage()).load("1"); app.setcurrent(new testcanvas());}protected void pauseapp() { app.pause();} |
这回是大功告成了。总结一下他的优点:
1、在需要返回前一屏的地方只需要一个app.restore();
2、自动处理暂停和恢复;
3、随时取得系统参数app.getproperty();
4、统一的错误处理;
5、整合多语言功能;
6、更方便的切换屏幕,只需要app.setcurrent()。
转载地址:http://sdedi.baihongyu.com/