开发者

Blackberry - problem with UiApplication.popScreen() on Blackberry OS 4.5

I have a application with a screen manager class that is causing me some problems. The application makes requests to the server to perform searches and allows the user to view results.

The application has worked fine on all OS versions up to 4.5 where we are sudden having problems viewing a screen under certain circumstances.

It occurs when the user has performed a search and they wait for the results. While waiting for results, they press the trackball which displays a menu. This is not needed to display the results, it just happened that the user decided to press it.

When the results come back from 开发者_JAVA技巧the server, the results screen should automatically be displayed. On OS 4.5, the code displays the results screen runs but then the application completely falls over. If the user doesn't press the trackball while waiting, the application works fine.

Looking at the logs, they show no exception being thrown and the only suspect line being

System data:VM:DPNAv=78,p

By adding in some more log lines I have discovered that the code is reaching the UiApplication.getUiApplication().popScreen(screen); line in the method hideScreen(Screen screen) but when called from hideCurrentScreen(). By adding in some more debugging I find that the active screen at this point is DefaultMenuScreen (as the menu button has been pressed)

So it seems the problem is that I am trying to pop one of my own screens from the display stack when the DefaultMenuScreen one is the active one. I repeat that this code did work on OS previous to 4.5. By running the same code on the 8300 with OS 4.2.2 with the debugging statements, I can see that the same thing happens, the active screen is the DefaultScreen but removing my own screen does not cause the whole application to crash.

The one way round this I could see, was to change the hideCurrentScreen() to just remove the active screen but this does not seem like the correct way to do it.

Has anyone else had experience of this? Can anyone tell me why this is happening? What are we meant to do if we cannot remove our screens when a DefaultMenuScreen is the active one?

This occurs in both device and simulator for 8310 and 9700.

The screen manager code is as follows.

public class ScreenManager
{ 
    private Hashtable screens;
    private String currentScreenName;

    public ScreenManager()
    {
        screens=new Hashtable();  
    }

    /**
     *  Description of the Method
     *
     *@param  sCardName  Description of Parameter
     */
    public boolean showScreen( String sScreenName )
    {
        boolean bSuccess=false;

        if (sScreenName != null && sScreenName.length() > 0 )
        {           
            MainScreen screen=(MainScreen)screens.get(sScreenName);

            if (screen!=null)
            {
                // We have a new screen to display so pop the current screen off the stack

                hideCurrentScreen();

                // If the screen is on the stack then pop the screens until we get our target screen
                // otherwise just push the screen onto the stack.

                if (screen.isDisplayed())
                {   
                    Screen activeScreen=null;
                    synchronized(UiApplication.getEventLock()) 
                    {
                        activeScreen=UiApplication.getUiApplication().getActiveScreen();
                    }

                    while (screen!=activeScreen && activeScreen!=null)
                    {
                        activeScreen=hideScreen(activeScreen);
                    }

                    bSuccess=(screen==activeScreen);
                }
                else
                {
                    synchronized(UiApplication.getEventLock()) 
                    {
                        UiApplication.getUiApplication().pushScreen(screen);
                        bSuccess=true;
                    }
                }
            }

        }

        if (bSuccess)
        {
            this.currentScreenName=sScreenName;
        }
        else
        {
            Logger.warning("ScreenManager: Failed to display screen ["+ sScreenName +"]");
        }

        return bSuccess;
    }

    private Screen hideCurrentScreen()
    {       
        Screen activeScreen=null;   

        if(currentScreenName!=null)
        {
            MainScreen screen=(MainScreen)screens.get(currentScreenName);
            activeScreen=hideScreen(screen);
        }

        return activeScreen;
    }


    private Screen hideScreen(Screen screen)
    {
        Screen activeScreen=null;       

        if (screen!=null && screen.isDisplayed())
        {
            Logger.finest("Hiding Screen ["+currentScreenName+"]");

            synchronized(UiApplication.getEventLock()) 
            {
                UiApplication.getUiApplication().popScreen(screen);
                activeScreen=UiApplication.getUiApplication().getActiveScreen();                
            }

            Logger.finest("Hid Screen ["+currentScreenName+"]");
        }                       

        return activeScreen;
    }  

    //Rest of code omitted 
}


The only way round this I managed to find was what I mentioned in the question. When I want to remove the current screen. I need to check it is the same as the active screen. If it is not the same then I just remove the active screen until I reach the screen I am looking for. This would only happen if a menu or pop up was displayed. Also, I need to add checks to my custom pop-up code to make sure it does not try and remove a screen that has already been removed.

It seems a bit messy but could not find any other alternatives.


The way we pop screens in our app is to explicitly pop the screen you want off the stack, as opposed to just the top-most screen. This either requires keeping track of which screens you have on the stack, or some code to iterate through the screens on the stack and search for the particular screen you want to pop off.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜