【发布时间】: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