【问题标题】:Blackberry - problem with UiApplication.popScreen() on Blackberry OS 4.5Blackberry - Blackberry OS 4.5 上的 UiApplication.popScreen() 问题
【发布时间】:2010-08-18 18:34:55
【问题描述】:

我有一个带有屏幕管理器类的应用程序,这给我带来了一些问题。 应用程序向服务器发出请求以执行搜索并允许用户查看结果。

该应用程序在我们突然遇到的最高 4.5 的所有操作系统版本上都运行良好 在某些情况下查看屏幕时出现问题。

当用户执行搜索并等待结果时发生。 在等待结果时,他们按下显示菜单的轨迹球。 这不是显示结果所必需的,只是碰巧用户决定按下它。

当结果从服务器返回时,结果屏幕应该会自动显示。在 OS 4.5 上,代码显示结果屏幕运行,但随后应用程序完全崩溃。如果用户在等待时没有按下轨迹球,则应用程序可以正常工作。

查看日志,它们显示没有抛出异常并且唯一可疑的行是

System data:VM:DPNAv=78,p

通过添加更多日志行,我发现代码已到达 UiApplication.getUiApplication().popScreen(screen); 方法 hideScreen(Screen screen) 中的行,但从 hideCurrentScreen() 调用时。通过添加更多调试,我发现此时的活动屏幕是 DefaultMenuScreen(因为已按下菜单按钮)

所以问题似乎是我试图从显示器中弹出我自己的屏幕之一 当 DefaultMenuScreen 一个是活动的时堆栈。我再说一遍,这段代码确实可以在 4.5 之前的操作系统上运行。通过在带有调试语句的 OS 4.2.2 的 8300 上运行相同的代码,我可以看到发生了同样的事情,活动屏幕是 DefaultScreen,但删除我自己的屏幕不会导致整个应用程序崩溃。

我可以看到的一种解决方法是将 hideCurrentScreen() 更改为仅删除活动屏幕,但这似乎不是正确的方法。

有其他人有过这方面的经验吗?谁能告诉我为什么会这样?如果在 DefaultMenuScreen 处于活动状态时我们无法移除屏幕,我们该怎么办?

这发生在 8310 和 9700 的设备和模拟器中。

屏幕管理器代码如下。

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 
}

【问题讨论】:

    标签: blackberry


    【解决方案1】:

    我设法找到的唯一方法是我在问题中提到的。当我想删除当前屏幕时。我需要检查它是否与活动屏幕相同。如果不一样,那么我只需删除活动屏幕,直到到达我正在寻找的屏幕。仅当显示菜单或弹出窗口时才会发生这种情况。此外,我需要向我的自定义弹出代码添加检查,以确保它不会尝试删除已删除的屏幕。

    看起来有点乱,但找不到任何其他选择。

    【讨论】:

      【解决方案2】:

      我们在应用中弹出屏幕的方式是显式地从堆栈中弹出您想要的屏幕,而不仅仅是最顶层的屏幕。这要么需要跟踪您在堆栈上拥有哪些屏幕,要么需要一些代码来遍历堆栈上的屏幕并搜索您想要弹出的特定屏幕。

      【讨论】:

      • 我可以理解,但我遇到的问题是,当按下菜单按钮时,堆栈顶部的屏幕是黑莓默认菜单屏幕。此时,如果我尝试弹出我自己的一个屏幕,应用程序会崩溃,不会抛出任何异常,让您了解发生了什么。除了删除黑莓菜单屏幕之外,我似乎没有办法处理这个问题。似乎这是在以前版本的操作系统中为您隐式完成的
      • 对不起 - 我误解了这个问题。这实际上听起来像一个错误。你说的“跌倒”是什么意思?彻底关闭?如果是这样,您可能希望在 RIM 的开发人员错误跟踪器中提交错误。
      • 没关系。也许我说得不够清楚。是的,应用程序完全关闭。我将查看开发人员错误跟踪器并查看有关提交错误的信息。感谢您的回复。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多