BlackBerry 一种多screen 管理方案

BlackBerry 一种多screen 管理方案

背景:
BlackBerry的显示堆栈(stack):
Screen对象在一个一组有序的Screen显示栈里得到维护。在栈顶的Screen对象是显示给用户的活动Screen。
当应用程序显示一个Screen时,它将这个Screen压入到栈顶。当关闭一个Screen,将这个Screen从栈里移出,然后显示栈里的下一个Screen,如果必要会重绘它。
每个Screen在栈里只出现一次。如果同一个Screen压入到栈不止一次,VM会抛出一个运行时异常。
当用户完成和Screen交互,应用程序必须将Screen从栈里移出,以致内存不必再用。
不要在同一时间里使用多个Screen,因为每个Screen使用独立的线程。

问题:
当一个BB程序里有很多个screen时,在堆栈里管理维护它们是一件很困难的事情。
例如,我们在页面跳转,更换screen时,将yigge新的screen压入栈中。
但也许,某些时候有要回到原来的某个screen。

这个时候,我们不能再压入同一个screen的相同实例。如前所述,VM会抛出一个运行时异常。
那么,我可以生成同一个screen的一个新的实例,压入栈顶。这样可以得到一个新的需要的screen,但是新的刚初始化的。
和那个在栈里的screen并非相同的实例有着不同的数据状态。

解决:
这里的解决方法是:
1 维持一个对象池(object pool),用于维护各个screen的实例。
  当客户需要一个之前的screen时,对象池给予客户它维护着的对应的screen实例。
  当客户要求的是一个新的页面的时候,它也能产生新的screen。
  在产生新的screen的时候,应该用新的screen覆盖对象池中的维护的同类的screen旧有实例。
 
  这样,就可以很灵活地得到一个screen的新的实例,或者得到一个screen之前的实例(用于前一次该页面的显示)。

2 而在 BlackBerry 的显示栈,任何时候只维持栈顶的一个screen。

3 需要显示某页时,在 对象池中找到对应的的 screen ,压入到显示栈。
  页面转换的时候,先将之前的screen从栈中弹出,再压入新的screen。
  
  net.rim.device.api.ui.UiApplication 是用于管理screen的类。
  popScreen(Screen screen) 用于弹出栈顶的screen,更新并显示栈中的下一个screen。
  pushScreen(Screen screen) 用于压入一个screen,更新并显示这个screen。
 
  net.rim.device.api.ui.Screen 类本身也可以控制自己的弹出。
  close() 用于弹出本身,但是有一个附加动作,要是本身是栈中最后一个screen,那么程序也将退出。
 
  这个解决办法里,栈里只维持一个screen。我们弹出这个screen后栈为空,但我们并不想退出程序,而是想压入新的screen。
  所以,栈操作都由UiApplication来完成。在这个解决办法里。

实例:

package  app.ui.screen;

import  app.ui.factory. * ;

public   class  ScreenPool 
{
    
private static InitScreen initScreen;
        
private static BusyScreen busyScreen;

        public static BusyScreen getBusyScreen( int type )
       {
           
if( type == BusyScreen.TYPE_SYNC )
                     busyScreen 
= new BusyScreen( BusyScreen.TYPE_SYNC ); 
           
else
                busyScreen 
= new BusyScreen( BusyScreen.TYPE_NORMAL );
            
        
return busyScreen;
     }

    
    
public static InitScreen getNewInitScreen()
     {
       InitScreenBuilder initScreenBuilder 
= new InitScreenBuilder();
       InitScreenDirector initScreenDirector 
= new InitScreenDirector( initScreenBuilder );
       initScreenDirector.construct();
       InitScreen _initScreen 
= initScreenBuilder.getResult(); 
       
       initScreen 
= _initScreen;
       
return _initScreen;
    }

    
    
public static InitScreen getPreviousInitScreen()
        {
        
return initScreen;
    }

    
}
 


第一次压入, 因为栈为空无须弹出screen,以后每次压栈都先弹出栈内唯一的screen, 使栈为空再压入新的screen:

pushScreen( ScreenPool.getBusyScreen( BusyScreen.TYPE_NORMAL ) );
或者
pushScreen( ScreenPool.getBusyScreen( BusyScreen.TYPE_SYNC) );

以后每次压入:
UiApplication.getUiApplication().popScreen(); 
UiApplication.getUiApplication().pushScreen( ScreenPool.getNewIntervListe());
或者
UiApplication.getUiApplication().popScreen(); 
UiApplication.getUiApplication().pushScreen( ScreenPool.getPreviousIntervListe());
或者
UiApplication.getUiApplication().popScreen(); 
UiApplication.getUiApplication().pushScreen( ScreenPool.getBusyScreen( BusyScreen.TYPE_NORMAL ) );

你可能感兴趣的:(BlackBerry 一种多screen 管理方案)