问题 每个使用Java ME工作的人必定会碰到在切换可显示的物件时这个“一闪而过(flicker)”的问题,例如从已经在View的一个画布设定一个新的画布,你会仔细想过可显示的画布不应该一次又一次地设定,我们在整个应用程式中应该只使用一个画布设定,而这样会产生一个长期不可管理的Canvas类别,这个类别会有很长的键盘按下/释放、绘製方法及一堆的Switch case / if then else等等,这样可会影响程式的效率及可读性。 解决方桉 我们必须以这样的一个方式设计一个解决方桉,这个方桉就是只有一个Canvas(BaseCanvas – 键下面的程式码)只有一次被midlet设为目前可显示的,且对不同的应用程式模组使用物件导向方法来建构不同的Canvas萤幕,这些模组可以藉由一个共同的介面类别物件在BaseCanvas传递而不用flicker,每个萤幕处理绘製及式键的程式码用这样不同的萤幕类别来分隔,这样可因此变得较易阅读及效率。 优点 容易扩展 教友效率的程式码 较可阅读的程式码 较低的记忆体佔用 程式码 BaseCanvas會在下面 import javax.microedition.lcdui.*; public class BaseCanvas extends Canvas { /**Singleton Instance**/ private static BaseCanvas mCanvas; /** Singleton Accessor Method with lazy initialization**/ public static Canvas getCanvas() {if(mCanvas==null) mCanvas=new BaseCanvac(); return mCanvas; } public CanvasScreen setCurrentScreen(CanvasScreen aCs) { CanvasScreen old=mCs; mCs=aCs; return old; } public void paint(Graphics g) { if(null!=mCs) mCs.paint(g); } public void keyPressed(int keyCode) { if(null!=mCs) mCs.keyPressed(keyCode); } public void keyRepeated(int keyCode) { if(null!=mCs) mCs.keyRepeated(keyCode); } /**Stratergy Object **/ private CanvasScreen mCs=null; private BaseCanvas() { setFullScreenMode(true); } } CanvasScreen介面會在下面 import javax.microedition.lcdui.*; public interface CanvasScreen { public void paint(Graphics g); public void keyPressed(int keyCode); public void keyRepeated(int keyCode); } 所有應用程式不同的模組的其他螢幕或canvas類別會在下面 (例如,SplashScreen) import javax.microedition.lcdui.*; public class SplashScreen implements CanvasScreen { BaseCanvas bc; public SplashScreen() { this.bc=BaseCanvas.getCanvas(); bc.setCurrentScreen(this); // do what you want to paint on splash screen and load your assests. } public void keyRepeated(int keyCode){ } public void paint(Graphics g) { // paint your Splash Screen // paint Loader(g); } public void keyPressed(int keyCode) { // do what you need } private void repaint() { bc.repaint(); } } 所有其他的萤幕类别将实做CanvasScreen介面,来执行他们自己的绘製及事件处理。 执行绪的安全 上面所说的存取BaseCanvas类别不是执行绪安全,不同执行绪的同时存取会造成不可预测的结果,所以假如一个应用程式从不同的执行绪存取这个类别那麽存取它应该是同步的。