使用TimerTask的Blackberry IllegalStateException错误

tpa*_*pae 3 java blackberry

我有一个实现MainScreen的启动画面,我正在尝试使用Timer等待3秒钟来推动新屏幕.

TimerTask splashTask = new TimerTask() {
    public void run() {
        UiApplication.getUiApplication().pushScreen(new HomeNavigationScreen());
    }
};

timer.schedule(splashTask, 3000);
Run Code Online (Sandbox Code Playgroud)

但是,它抛出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]

and*_*soj 6

基于原始问题的诊断:

您的第一个步骤应该是阅读文档定时器和TimerTask,这给出了一个满足下列条件IllegalStateExceptionschedule(...):

如果计时器的任务执行线程意外终止,例如,因为调用了stop方法,则在计时器上调度任务的任何进一步尝试都将导致IllegalStateException,就像调用了计时器的cancel方法一样.

.stop()有点吗?你打过电话cancel()吗?你能检查一下这个任务是否引发了一个突然终止该Timer线程的异常吗?你是否正在使用Timer其他的TimerTasks?你相信他们吗?

尝试TimerTask使用广泛的异常处理程序包装逻辑,并让它直接报告以查看是否存在内部意外异常,这将导致下一次调用schedule失败,如上所述.

此外,一个挑剔,但重要的一个:当问一个包含"为什么我得到这个例外?"的问题时的最佳做法.是包括完整的异常和堆栈跟踪输出.您将获得更高质量的答案,您不必再次阅读此文本,然后必须重新编辑您的问题等.

针对您的具体错误的指导:

好吧,阅读异常声明.看起来你已经打乱了UI引擎.所以你有两个问题:

  1. 你把计时器线程交给一个未被捕获的异常爆炸的任务,这让你感到不安.将这些东西包装在一个try/catch块中的好策略,其中catch操作至少是打印或记录可用的堆栈跟踪并重新抛出异常.

  2. 你已经打乱了UI事件逻辑,见下文......

我不知道黑莓UI,但可能你想要做的事情需要在GUI事件循环中完成.此KB条目应该有所帮助.更好的是,阅读API文档.您需要保持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);
Run Code Online (Sandbox Code Playgroud)

或者,不太可能引入同步问题和潜在的死锁:

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);
Run Code Online (Sandbox Code Playgroud)