Java Blackberry IllegalStateException使用TimerTask时出错
我有一个实现MainScreen的启动屏幕,我正在尝试使用计时器等待3秒来推送一个新屏幕Java Blackberry IllegalStateException使用TimerTask时出错,java,blackberry,Java,Blackberry,我有一个实现MainScreen的启动屏幕,我正在尝试使用计时器等待3秒来推送一个新屏幕 TimerTask splashTask = new TimerTask() { public void run() { UiApplication.getUiApplication().pushScreen(new HomeNavigationScreen()); } }; timer.schedule(splashTask, 3000); 然而,它抛出了非法状态异常错
TimerTask splashTask = new TimerTask() {
public void run() {
UiApplication.getUiApplication().pushScreen(new HomeNavigationScreen());
}
};
timer.schedule(splashTask, 3000);
然而,它抛出了非法状态异常错误,我不确定我做错了什么
我是eclipse和java新手,不知道如何查看堆栈跟踪
以下是我的发现:
ApplicationManagerImpl.processExited : process process switching to background: pid=260
java.lang.IllegalStateException: UI engine accessed without holding the event lock.
Timer died: Thread[Thread-310688768,5]
ApplicationManagerImpl.processExited:进程切换到后台:pid=260
java.lang.IllegalStateException:在不持有事件锁的情况下访问UI引擎。
计时器死机:线程[Thread-310688768,5]
基于原始问题的诊断:
您的第一步应该是阅读和TimerTask的文档,该文档为计划(…)
中的非法状态异常提供了以下条件:
如果计时器的任务执行线程
例如,意外终止,
因为调用了它的stop方法,
计划任务的任何进一步尝试
打开计时器将导致
IllegalStateException,好像
计时器的取消方法已被禁用
调用
您是否在某个时候.stop()
?您是否调用过cancel()
?您是否可以检查任务是否引发了异常,该异常突然终止了计时器
线程?您是否对其他TimerTask
s使用相同的Timer
?你相信他们吗
尝试使用广泛的异常处理程序包装您的TimerTask
逻辑,并让它直接报告是否存在内部意外异常,这将导致对schedule
的下一次调用失败,如上所述
另外,一个很挑剔但很重要的问题是:当问一个包括“为什么我会得到这个异常?”的问题时,最好的做法是包括完整的异常和堆栈跟踪输出。你将得到更高质量的答案,你不必再次阅读本文,然后重新编辑你的问题,等等
针对具体错误的指导:
那么,请阅读例外声明。看起来你搞乱了UI引擎。所以你有两个问题:
你已经打乱了计时器线程,因为你交给它一个任务,这个任务会导致一个未捕获的异常。将这些内容包装在try/catch
块中的好策略,其中catch
操作至少是以打印或记录可用的堆栈跟踪并重新抛出异常
您已经打乱了UI事件逻辑,请参见下文
我不知道blackberry UI,但您尝试执行的操作可能需要在GUI事件循环中完成。这应该会有所帮助。更妙的是,阅读这篇文章。要调用pushScreen()
,需要保持GUI锁,就像在Swing中一样。一种方法是将代码更改为通过或invokeAndWait()
调用
候选代码
这是未经测试,因为我从来没有也不打算做任何黑莓开发,但它编译在我的脑海中对公布的黑莓API,FWIW。尝试以下方法之一:
TimerTask splashTask = new TimerTask()
{
public void run() {
final UiApplication uia = UiApplication.getUiApplication();
final Object eventLock = uia.getEventLock();
synchronized(eventLock) {
uia.pushScreen(new HomeNavigationScreen());
}
}
};
timer.schedule(splashTask, 3000);
或者,不太可能引入同步问题和潜在死锁:
TimerTask splashTask = new TimerTask()
{
public void run() {
final UiApplication uia = UiApplication.getUiApplication();
uia.invokeLater(new Runnable() {
public void run() {
uia.pushScreen(new HomeNavigationScreen());
});
}
}
};
timer.schedule(splashTask, 3000);
正如Andersoj指出的,您正在尝试在不持有UI事件锁的情况下进行UI更改。
invokeLater是一种让代码执行并安全地进行UI更改的机制
TimerTask splashTask = new TimerTask() {
public void run() {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().pushScreen(new HomeNavigationScreen());
}
}
}
};
timer.schedule(splashTask, 3000);
我没有调用cancel()或stop()。。我只有一个计时器和一个计时器任务。我不知道如何查看完整异常和堆栈跟踪输出。如果您的设备阻止您查看完整异常报告,您的第一步应该是找出如何获取该报告。大概它是自动记录在某个地方的,或者您可以自己记录(将对schedule的调用包装在try/catch中,捕获非法状态异常,并在其上调用printStackTrace()
,最坏的情况。)@Michael Donohue:OOPS。剪贴故障。在这里: