【问题标题】:Cancel a timer in BlackBerry - Java在 BlackBerry 中取消计时器 - Java
【发布时间】:2013-02-21 05:54:56
【问题描述】:

我正在使用具有多个计时器的 BlackBerry 应用程序来安排将报告发送到服务器平台。在我更改逻辑以优先报告报告之前,一切正常。因此,现在我正在检查,例如,报告 A 是否已打开并且用户也激活了报告 B,那么只有报告 B 应该通过并且报告 A 应该停止直到 B 被激活。一旦 B 被停用(定时器取消),报告 A 应该恢复。但是,即使代码在取消定时器任务代码中循环,报告 A 仍会继续执行,而 B 仍处于激活状态。

FieldChangeListener reportingListener = new FieldChangeListener() {   
        public void fieldChanged(Field field, int context) 
        {
            try {

            if (field == slider) {
                int i = slider.getValue();
                if(i==0) 
                    lblInterval.setText(1+" minute");
                if(i==1) 
                    lblInterval.setText(2+" minutes");
                if(i==2) 
                    lblInterval.setText(5+" minutes");
                if(i==3) 
                    lblInterval.setText(10+" minutes");
                if(i==4) 
                    lblInterval.setText(15+" minutes");
                if(i==5) 
                    lblInterval.setText(30+" minutes");
                if(i==6) 
                    lblInterval.setText(1+" hour");
                if(i==7) 
                    lblInterval.setText(2+" hours");
                if(i==8) 
                    lblInterval.setText(6+" hours");
                if(i==9) 
                    lblInterval.setText(12+" hours");
                if(i==10) 
                    lblInterval.setText(24+" hours");
                setSliderPosition(i);
                value=setLblIntervalValue(i);
                value2=setGpsTimerIntervalValue(i);
                gpsReportValue=lblInterval.getText();
                gpsIntervalValue1=setGpsTimerIntervalValue(i);
            }

            if (PersistentStoreHelper.persistentHashtable.containsKey("image")) 
                 {
            boolean trackONOFFImage = ((Boolean) PersistentStoreHelper.persistentHashtable.get("image")).booleanValue();
            if(trackONOFFImage==true)
            {
                if (PersistentStoreHelper.persistentHashtable.containsKey("panic"))
                 {
                     boolean panicImage = ((Boolean)PersistentStoreHelper.persistentHashtable.get("panic")).booleanValue();
                     if(panicImage==true)
                     {
                         MyScreen.currentlyReporting.setText("PANIC ALARM TRIGGERED");
                         if (PersistentStoreHelper.persistentHashtable.containsKey("tabTrackValid"))
                     {
                         boolean trackingTab = ((Boolean)PersistentStoreHelper.persistentHashtable.get("tabTrackValid")).booleanValue();
                         if(trackingTab==false)
                         {
                            trackSlider.cancel();
                         }
                        PersistentStoreHelper.persistentHashtable.put("tabTrackValid", Boolean.TRUE);
                     }

                     }
                     else
                     {
                        //int gpsIntervalValue1=setGpsTimerIntervalValue(i);
                    if (PersistentStoreHelper.persistentHashtable.containsKey("gpsTimerIntervalValue")) 
                     {
                        String intervalValue=((String)PersistentStoreHelper.persistentHashtable.get("gpsTimerIntervalValue"));
                        if(gpsIntervalValue1==Integer.parseInt(intervalValue))
                        {
                            //do nothing
                        }
                        else
                        {
                            trackSlider = new TimerTask() {
                                 public void run() {

                                    try {
                                        UiApplication.getUiApplication().invokeLater(new Runnable() 
                                        {
                                            public void run() {
                                               //Dialog.alert("Invalid login details");
                                            }
                                        });
                                        sendTrackingReport();
                                    } catch (Exception e) {
                                        Dialog.alert("Unable to track at the new interval set");
                                    }

                                 }
                              };
                              //trackSlider.run();
                              trackingTimerSlider.scheduleAtFixedRate(trackSlider , 0, gpsIntervalValue1);
                             PersistentStoreHelper.persistentHashtable.put("tabTrackValid", Boolean.FALSE);
                        }
                     }
                     }
                 }

            }//this
                }

        } catch (IllegalStateException e) {
            //Dialog.alert("CANCEL TRACK1");
            e.printStackTrace();
        } catch (NullPointerException e) {
            //Dialog.alert("CANCEL TRACK2");
            e.printStackTrace();
        }
        }   
     }; 

注意:报告 A = 跟踪。报告 B = 恐慌。恐慌优先于跟踪。滑块正在更改计时器间隔值。

我调试了我的代码,当它进入循环并取消所请求报告的计时器任务时,我仍然看到这些报告正在通过。我没有正确取消计时器吗?请指教。

【问题讨论】:

  • 通过阅读您的问题很明显,您会得到所谓的Race Condition 顺便说一句。您可以使用MonitorMutual Exclusion 轻松解决。
  • 尝试将同步添加到您的fieldChanged。即synchronized public void fieldChanged(Field field, int context),这将给出方法fieldChanged互斥。
  • @Killrawr 感谢您的评论。我应该如何使用互斥?你能指导吗?我遇到了 ScheduledExecutorService。我也从未实施过,但这将有助于解决。为什么当我调用 .cancel() 时我的计时器任务没有取消?请指导。
  • 实现mutual exclusion的方法不止一种,我不介意模拟一些例子。但我需要你的是一段代码示例(没有膨胀,最好是 pastebin?)你希望mutual exclusion 发生(更多细节here)。问候
  • @Killrawr 好吧。你介意来个聊天室让我们讨论一下吗?

标签: blackberry java-me timer


【解决方案1】:

来自TimerTask.cancel javadoc

...如果任务已被安排重复执行,它将永远不会再次运行。 (如果此调用发生时任务正在运行,则任务将运行到完成,但永远不会再次运行。) ...

首先,从线程调用cancel 不会立即停止 Timer 线程,如您所见。

您每次都在屏幕上创建一个新计时器:

trackSlider = new TimerTask()

因此,如果您在应用运行期间创建多个屏幕实例,则可能会创建多个相同类型的计时器。

【讨论】:

  • 感谢您的回答。确实有帮助。我每次都创建一个新计时器的事实是因为我有像 ON 和 OFF 这样的按钮。我无法重复使用已取消的计时器。因此,为了再次运行相同的计时器任务,我正在重新创建它。这种方法不正确吗?
  • 我会说这很危险,因为在切换到另一个屏幕时很容易让线程运行。确保在创建新的之前杀死旧的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-08
  • 2017-09-26
  • 2013-11-05
  • 2016-08-01
  • 1970-01-01
相关资源
最近更新 更多