blackberry的screen类似于android平台的activity,都是用来作为UI显示的容器,并且blackberry也提供类似于androidManager来自我管理ui的栈,但不足的是,blackberry的screen没有生命周期的概念,于是作者试图借鉴android对activity的管理方式来管理blackberry的screen栈。
基本思路是这样的,我应用中的screen设计一个父类,里面抽象出screen的四种状态(生命周期)
/**
* FileName: Screen.java
* @Description: TODO(用一句话描述该文件做什么)
* All rights Reserved, Designed By 21winmess
* Copyright: Copyright(C) 2010-2011
* * @author: Matrix xu
* @version V2.0
* Createdate: 2012-7-11 下午5:26:50
*
* Modification History:
* Date Author Version Discription
* -----------------------------------------------------------------------------------
* 2012-7-11 Qute_Android2.0
* Why & What is modified: <修改原因描述>
*/
import net.rim.device.api.ui.container.MainScreen;
/**
* @ClassName: Screen
* @Description:所有的页面应实现这个抽象父类,提供生命周期回调函数
* @author: Matrix
* @date: 2012-7-11 下午5:26:50
*
*/
public abstract class BaseMainScreen extends MainScreen {
private boolean isPause = false;
private Intent intent;
public BaseMainScreen() {
}
public BaseMainScreen(long style) {
super(style);
}
/**
* @return the isPause
*/
public boolean isPause() {
return isPause;
}
/**
* @param isPause
* the isPause to set
*/
public void setPause(boolean isPause) {
this.isPause = isPause;
}
/**
* @return the intent
*/
public Intent getIntent() {
if (this.intent == null) {
intent = new Intent();
}
return intent;
}
/**
* @param intent
* the intent to set
*/
public void setIntent(Intent intent) {
this.intent = intent;
}
/**
* When screen is created on fisrt time,FromFactory will invoke this
* method,so you can init the screen instance and properties at this time.
*/
protected abstract void onCreate();
/**
* When screen is visiable,the method is invoked,but this methord is only
* execute once...
*/
protected abstract void onShow();
/**
* when the screen is not visable,but still be in screen stack.
*/
protected abstract void onPause();
/**
* When screen is pop from stack, the method is invoked..
*/
protected abstract void onFinish();
protected boolean onSavePrompt() {
return true;
}
}
解释一下4个回调函数的含义:(如果熟悉android activity的生命周期那么理解起来就很容易了)
1.onCreate() 创建该画面的时刻被回调
2.onShow() 画面被显示的时候被回调(这里面要配合 UiApplication.getUiApplication().pushScreen(screenInstance);)
3.onPause()该画面被挂到后台的时候被调用
4.onFinish()该画面被回收的时候被调用(这里要配合UiApplication.getUiApplication().popScreen(screenInstance);)
之后我又设计了一个管理screen的容器 ScreenFactory,代码如下:
/**
* FileName: ScreenManager.java
* @Description: TODO(用一句话描述该文件做什么)
* All rights Reserved, Designed By 21winmess
* Copyright: Copyright(C) 2010-2011
* @author: Matrix xu
* @version V2.0
* Createdate: 2012-7-11 下午6:12:09
*
* Modification History:
* Date Author Version Discription
* -----------------------------------------------------------------------------------
* 2012-7-11 Qute_Android2.0
* Why & What is modified: <修改原因描述>
*/
import java.util.Stack;
import net.rim.device.api.ui.UiApplication;
/**
* @ClassName: ScreenManager
* @Description:用于管理screen的实例
* @author: Matrix
* @date: 2012-7-11 下午6:12:09
*
*/
public class ScreenFactory {
private static Stack screenStack = new Stack();
/**
* get current screen be showing
*
* @return
*/
public BaseMainScreen currentScreen() {
BaseMainScreen screenInstance = null;
if (!screenStack.empty()) {
screenInstance = (BaseMainScreen) screenStack.lastElement();
}
return screenInstance;
}
/**
* pause a screen instance
*
* @param screenInstance
*/
private void screenPause(BaseMainScreen screenInstance) {
if (!screenInstance.isPause()) {
screenInstance.setPause(true);
}
screenInstance.onPause();
}
/**
* show screen which you want
*
* @param screenClass
* @param intent
*/
public void screenShow(Class screenClass, Intent intent) {
BaseMainScreen currentScreen = this.currentScreen();// 先获得当前栈顶的对象
BaseMainScreen screenInstance = this.screenIsContained(screenClass);
if (screenInstance != null) {
screenStack.removeElement(screenInstance);// 先删掉,然后再push到stack
try {
UiApplication.getUiApplication().popScreen(screenInstance);
} catch (Exception e) {
}
} else {
screenInstance = this.screenCreate(screenClass);
}
if (intent != null) {
screenInstance.setIntent(intent);
}
if (screenInstance.isPause()) {
screenInstance.setPause(false);
}
screenInstance.onShow();
screenStack.push(screenInstance);
if (currentScreen != null) {
screenPause(currentScreen);// 停止之前栈顶的对象,应该是被压入到栈的第二位
}
try {
UiApplication.getUiApplication().pushScreen(screenInstance);
} catch (Exception e) {
}
}
/**
* finish or remove the screen
*
* @param screenClass
*/
public void screenFinish(Class screenClass) {
BaseMainScreen screenInstance = this.screenIsContained(screenClass);
if (screenInstance == null)
return;
this.screenPause(screenInstance);
screenInstance.onFinish();
screenStack.removeElement(screenInstance);
UiApplication.getUiApplication().popScreen(screenInstance);
}
/**
* check the screen is contained in screen stack
*
* @param screenClass
* @return
*/
public BaseMainScreen screenIsContained(Class screenClass) {
BaseMainScreen screenInstance = null;
for (int i = 0; i < screenStack.size(); i++) {
screenInstance = (BaseMainScreen) screenStack.elementAt(i);
if (screenClass.isInstance(screenInstance)) {
return screenInstance;
}
}
return null;
}
/**
* create a new screen instance by its clazz
*
* @param screenClass
* @return
*/
private BaseMainScreen screenCreate(Class screenClass) {
BaseMainScreen newScreen = null;
try {
screenClass = Class.forName(screenClass.getName());
newScreen = (BaseMainScreen) screenClass.newInstance();
newScreen.onCreate();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return newScreen;
}
// ======================单例模式===========================//
private static ScreenFactory mSingleInstance = null;
private static Object mSyncObject = new Object();
public static ScreenFactory getSingleInstance() {
synchronized (mSyncObject) {
if (mSingleInstance == null)
mSingleInstance = new ScreenFactory();
}
return mSingleInstance;
}
}
这个类主要完成的事情就是管理应用中的所有screen画面,并在适当的时刻去回调父类screen的回调函数。