У меня есть приложение с классом диспетчера экрана, которое вызывает у меня некоторые проблемы.
Приложение отправляет запросы на сервер для выполнения поиска и позволяет пользователю просматривать результаты.
Приложение работало нормально на всех версиях ОС до 4.5, где у нас внезапно появилось
проблемы с просмотром экрана при определенных обстоятельствах.
Это происходит, когда пользователь выполнил поиск и ожидает результатов.
В ожидании результатов они нажимают трекбол, который отображает меню.
Это не нужно для отображения результатов, просто получилось, что пользователь решил нажать на него.
Когда результаты возвращаются с сервера, экран результатов должен автоматически отображаться. В OS 4.5 код отображает экран результатов, но затем приложение полностью падает. Если пользователь не нажимает трекбол во время ожидания, приложение работает нормально.
Глядя на журналы, они не показывают выбрасываемых исключений и единственной подозрительной строкой является
System data:VM:DPNAv=78,p
Добавив еще несколько строк журнала, я обнаружил, что код достигает
. UiApplication.getUiApplication () popScreen (экран);
строка в методе hideScreen (Экран экрана), но при вызове из hideCurrentScreen (). Добавив еще несколько отладок, я обнаружил, что в данный момент активным экраном является DefaultMenuScreen (при нажатии кнопки меню)
Так что, похоже, проблема в том, что я пытаюсь открыть один из своих экранов с дисплея
стек, когда DefaultMenuScreen один является активным. Я повторяю, что этот код работал на ОС до 4.5. Запустив тот же код на 8300 с OS 4.2.2 с операторами отладки, я вижу, что происходит то же самое, активный экран - 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
}