03-28-2011 04:17 PM - edited 03-28-2011 04:27 PM
It happens when this code is run:
public void popMyScreen(){
if (screen != null){
Application.getApplication().invokeLater( new Runnable(){
public void run() {
try{
UiEngine ui = Ui.getUiEngine();
ui.popScreen(screen);
}catch(Throwable e){
if (TasteMyCity.getDebug())TasteMyCity.writelog("**** *** TasteMyCity popMyScreen ",e);
screen=null;
}
}
});
}
}
The method gets called from a number of places in my code - but sine I put everything in the Ui thread I thought it would work like this.
PS: That error message is what goes in my log, but the stack trace also has this:
GraphicsInternal.updateDisplayFromBackBuffer(int, int, int, int, int, int) line: 1132
UiEngineImpl.removeScreenInternal(Screen) line: 2001
Solved! Go to Solution.
03-28-2011 06:18 PM
Are you 100% sure that this code is actually being invoked from your Application? Is it being invoked from your alternate entry or from a listener that is perhaps running in another Application?
03-28-2011 06:52 PM
Yes, it gets invoked from fieldchange listeners in other screens' buttons. in in onexposed and onclose methods.
03-28-2011 07:25 PM
Most if not all of these are actually already running on the Event Thread, so you are making work for yourself. In addition, given that you have enclosed the code in an invokeLater, you do not need to use the UiEngine approach to finding the current UiApplication - you can just use UiApplication.getUiApplication()...
Can I ask you to change the code as follows, but put debugging statements in the 'exceptions' I note so we can figure out what exceptions are taking place. You could throw a RuntimeException at each point if you wanted, that would get us a Stack Trace at least.
public void popMyScreen(){
if (screen != null) {
Application screenApp = screen.getApplication();
if ( screenApp == null ) {
// Believe this means the screen has already been popped
return;
}
final UiApplication runningApp = UiApplication.getUiApplication();
if ( runningApp != screenApp ) {
// this app can't pop the screen anyway!
return;
}
if ( !(runningApp instanceof <yourApp>) ) {
// Not running our application!!
// Should we be popping other people's screen?
return;
}
if ( UiApplication.isEventDispatchThread() ) {
runningApp.popScreen(screen);
screen = null;
return;
}
runningApp.invokeLater( new Runnable(){
public void run() {
try{
runningApp.popScreen(screen);
}catch(Throwable e){
if (TasteMyCity.getDebug()) TasteMyCity.writelog("******* TasteMyCity popMyScreen ",e);
screen=null;
}
}
});
}
}
03-29-2011 09:16 AM
Thanks again Peter,
Using your code what usually happens in initial testing is that the method exits on the first return, sometimes it exits on the 4th return. No exceptions so far.
03-29-2011 10:25 AM
Then I suspect the problem was every now and again, for some reason, your were popping the same screen twice (the first return).
The 4th return is just a short cut, saves using the invokeLater. The invokeLater would work also.
Actually now that I review that code, I can see a change I would like to make:
Replace this:
runningApp.invokeLater( new Runnable(){
public void run() {
try{
runningApp.popScreen(screen);
}catch(Throwable e){
if (TasteMyCity.getDebug()) TasteMyCity.writelog("******* TasteMyCity popMyScreen ",e);
screen=null;
}
}
});
with
final Screen screenToPop = screen;
screen = null;
runningApp.invokeLater( new Runnable(){
public void run() {
try{
runningApp.popScreen(screenToPop);
}catch(Throwable e){
if (TasteMyCity.getDebug()) TasteMyCity.writelog("******* TasteMyCity popMyScreen ",e);
}
}
});