隨筆 - 35  文章 - 21  trackbacks - 0
          <2008年8月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          31123456

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          文章分類

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          背景:
          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 ) );

          posted on 2008-08-28 04:15 lincode 閱讀(468) 評論(0)  編輯  收藏 所屬分類: Blackberry
          主站蜘蛛池模板: 新郑市| 崇仁县| 乌海市| 融水| 临沭县| 棋牌| 霍林郭勒市| 盐城市| 宜黄县| 十堰市| 毕节市| 西平县| 嘉定区| 鄂托克旗| 德保县| 宜昌市| 北宁市| 汉源县| 浮梁县| 灵石县| 拉萨市| 鄱阳县| 嘉黎县| 河南省| 波密县| 安义县| 荃湾区| 乌兰察布市| 巴中市| 隆德县| 东宁县| 新兴县| 海晏县| 清水县| 濮阳县| 博罗县| 昌都县| 长武县| 临武县| 张家界市| 邵武市|