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的回調函數。