Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Blackberry IllegalStateException使用TimerTask时出错_Java_Blackberry - Fatal编程技术网

Java Blackberry IllegalStateException使用TimerTask时出错

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); 然而,它抛出了非法状态异常错

我有一个实现MainScreen的启动屏幕,我正在尝试使用计时器等待3秒来推送一个新屏幕

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。剪贴故障。在这里: