2013-02-21 61 views
1

我正在與BlackBerry App一起使用,該應用程序中包含多個計時器,用於計劃向服務器平臺發送報告。這一切都工作正常,直到我改變邏輯優先報告。因此,現在我正在檢查是否開啓了報告A並且用戶也激活了報告B,那麼只有報告B應該通過,並且報告A應該停止直到B被激活。一旦B被取消激活(取消定時器),應恢復報告A.但是,即使代碼在取消定時器任務代碼中循環,報告A仍繼續通過,但B仍處於激活狀態。取消BlackBerry中的計時器 - Java

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 =恐慌。恐慌優先於跟蹤。滑塊正在改變定時器間隔值。

我調試了我的代碼,當它進入循環並取消所請求報表的計時器任務時,我仍然看到這些報表正在經歷。我沒有正確取消計時器嗎?請指教。

+0

從閱讀你的問題,它的相當明顯你順便得到什麼叫'種族條件'。你可以通過使用'Monitor'和'Mutual Exclusion'來解決這個問題。 – Killrawr 2013-02-21 06:09:31

+0

嘗試通過添加同步到你的'fieldChanged'。即'synchronized public void fieldChanged(Field field,int context)',這會給方法'fieldChanged'互斥。 – Killrawr 2013-02-21 06:14:59

+0

@Killrawr感謝評論。我應該如何使用相互排斥?你能指導嗎?我遇到過ScheduledExecutorService。我從來沒有實現過,但這會幫助解決。爲什麼當我調用.cancel()時,我的計時器任務不會取消?請指導。 – Sarah 2013-02-21 07:26:42

回答

4

TimerTask.cancel javadoc

...如果任務已經安排爲重複執行,則永遠不會再運行。 (如果發生此調用時正在運行的任務,該任務將運行完,但永遠不會再運行。)...

因此,首先,調用cancel從一個線程不會立刻停止定時器線程,你可以看到。

而且要創建在你的屏幕每一次新的定時器:

trackSlider = new TimerTask() 

因此,如果您的應用程序運行時創建屏幕的多個實例,同一類型的幾個定時器有可能會被創建。

+0

感謝您的回答。確實有幫助。我每次創建一個新計時器的事實是因爲我有ON和OFF等按鈕。我無法重用我已經取消的計時器。因此,爲了再次運行相同的計時器任務,我正在重新創建它。這種方法不正確嗎? – Sarah 2013-02-25 04:52:25

+1

我想說這很危險,因爲在更換到另一個屏幕時很容易讓線程運行。確保你在創建新的之前殺死舊的。 – 2013-02-25 10:06:41