java - 使用 TimerTask 的黑莓 IllegalStateException 错误

标签 java blackberry

我有一个实现 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 引擎。所以你有两个问题:

  1. 您交给计时器线程的任务因未捕获的异常而崩溃,打乱了计时器线程。将这些东西包装在 try/catch block 中的好策略,其中 catch 操作至少打印或记录可用的堆栈跟踪和重新抛出异常。

  2. 您扰乱了 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/

相关文章:

blackberry - BlackBerry 上的 session 信息丢失(ColdFusion 应用程序)

debugging - 有没有办法在黑莓中以字符串的形式获取异常的堆栈跟踪?

java - 为什么使用堆栈容器速度较慢?

java - 如何传递:object values from html to controller

java - Jackson Objectmapper 读取具有可变字段/值类型的对象

android - 如何将 android 应用程序移植到黑莓?

BlackBerry RichMapField 在设备上为空白

blackberry - 如何在黑莓中用java检查互联网连接

java - Hackerrank 不接受有效的解决方案

java - Maven 2 & 打包 ejb 与 jar