我有一个实现 MainScreen 的初始屏幕,我正在尝试使用 Timer 等待 3 秒以推送一个新屏幕。
TimerTask splashTask = new TimerTask() {
public void run() {
UiApplication.getUiApplication().pushScreen(new HomeNavigationScreen());
}
};
timer.schedule(splashTask, 3000);
但是,它会抛出 IllegalStateException 错误,我不确定我做错了什么?
我是 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]
最佳答案
根据原题诊断:
您的第一步应该是阅读 Timer 的文档和 TimerTask,它为 schedule(...)
处的 IllegalStateException
提供以下条件:
If the timer's task execution thread terminates unexpectedly, for example, because its stop method is invoked, any further attempt to schedule a task on the timer will result in an IllegalStateException, as if the timer's cancel method had been invoked.
你在某个时候.stop()
了吗?你调用过cancel()
吗?你能检查一下任务是否抛出了突然终止 Timer
线程的异常吗?您是否对其他 TimerTask
使用相同的 Timer
?你信任他们吗?
尝试用广泛的异常处理程序包装您的 TimerTask
逻辑,并让它直接报告以查看是否存在内部意外异常,这会导致下一次调用 schedule
到如所述失败。
另外,一个挑剔但很重要的一个问题:提出包括“为什么我会得到这个异常?”这样的问题时的最佳实践。是包括完整的异常和堆栈跟踪输出。您将获得更高质量的答案,并且您不必再次阅读本文,然后重新编辑您的问题等。
具体错误指南:
好吧,阅读异常声明。看起来你已经扰乱了 UI 引擎。所以你有两个问题:
您交给计时器线程的任务因未捕获的异常而崩溃,打乱了计时器线程。将这些东西包装在
try/catch
block 中的好策略,其中catch
操作至少打印或记录可用的堆栈跟踪和重新抛出异常。您扰乱了 UI 事件逻辑,请参阅下文...
我不知道黑莓用户界面,但大概您要尝试做的事情需要在 GUI 事件循环中完成。这KB entry应该有帮助。更好的是,阅读 API documentation .您需要保持 GUI 锁定,就像在 Swing 中一样,以调用 pushScreen()
。一种方法是更改您的代码以通过 invokeLater()
调用或 invokeAndWait()
。
候选人代码
这是未经测试的,因为我从来没有也不打算进行任何 BlackBerry 开发,但在我看来它是根据已发布的 BlackBerry 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);
关于java - 使用 TimerTask 的黑莓 IllegalStateException 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3980854/