2010-11-03 60 views
1

執行我正在寫黑莓秒錶應用(其類似於內置秒錶黑莓)。有一個定時器標籤以MM:SS:T(分,秒,十分之一秒)的格式顯示當前時間。使用TimerTask標籤每100毫秒刷新一次。TimerTask的不以預定間隔

的應用工作得很好,時間爲正確顯示,但是,也有某些時刻計時器標籤不被更新以預定間隔(每100毫秒)。定時器標籤暫停(不包括)了一會兒,繼續計數(同時仍然能正確顯示時間)

我的想法是不執行TimerTask的這個暫停期間更新計時器標籤。你知道爲什麼這款應用會以這種方式行事,以及如何解決它?

以下是更新計時器標籤的主題:

public class ThreadUpdateTime extends Thread 
{ 
    private MyMainScreen myMainScreen; 
    private Timer updateTimerLabelTimer = new Timer(); 

    public ThreadUpdateTime(MyMainScreen parent) 
    { 
    myMainScreen=parent; 
    } 

    public void run() 
    { 
    try { 
     updateTimerLabelTimer.schedule(new RecordTimer(myMainScreen), TIMER_DELAY, TIMER_INTERVAL); 

    } catch (Exception e) { 
     //put alert here 
    } 
    } 

    public void iStop() 
    { 
    updateTimerLabelTimer.cancel(); 
    } 
} 

一個TimerTask:

public class RecordTimer extends TimerTask 
{ 
    private MyMainScreen myMainScreen; 
    public RecordTimer(MyMainScreen parent) 
    { 
    myMainScreen=parent; 
    } 

    public void run() 
    { 
    myMainScreen.iUpdateTimerLabel(); 
    } 
} 

和iUpdateTimerLabel方法:

public void iUpdateTimerLabel() 
{ 
//calculate : sign, sMin, sSec, sTenth  

    synchronized(Application.getEventLock()) 
    { 
    lblSpotTime.setText(sign+sMin+":"+sSec+"."+sTenth+" "); 
    }  
} 
+1

建議您發佈您的'TimerTask'的代碼以及將其提交給'Timer'的代碼。 – andersoj 2010-11-03 21:57:39

+0

這可能與計時器無關,特別是。請參閱相關:http://stackoverflow.com/questions/2569468/how-do-i-update-blackberry-ui-items-from-a-thread – andersoj 2010-11-04 00:00:55

回答

2

首先是衡量..記錄你的時間任務開始和結束時的時間戳,看看它是不是真的是'真的是這個問題。隨着在手,兩件事情發生到我的,

  1. 你的任務阻塞(也許在 一些UI的事情)?
  2. 同樣都是 Timer實例有其他任務?我不知道它是如何指定的,但任務可能都在單個線程上運行,所以如果有其他任務阻礙,那麼您的任務可能無法按指定的時間間隔運行。
  3. 是您TimerTask與UI事件循環正確同步(即是更新標籤的正確runLater()或任何方法,通過黑莓UI提供的)?如果你沒有這樣做,UI事件循環可能不會注意到你已經改變了標籤。我認爲在黑莓手機上,正確的事情是invokeLater()或者invokeAndWait(),這取決於你想要完成什麼。

編輯的代碼發佈後:

一對夫婦的有用和相關的資源here

  1. OK,我還是儀器說一些日誌或調用的println輸出在運行時 時間戳代碼。
  2. 不知道爲什麼schedule()調用自己的Runnable裏面......你不需要這一點,但也許你的應用程序在做,由於某種原因,我不能看。如果你認爲你正在爲計時器創建一個明確的線程,那麼你不是。您可能只需創建Timer,並從任何應用程序線程設置的位置調用schedule()即可。 Timer包含將執行此項工作的俘虜線程,並且介紹另一個線程可能是多餘且令人困惑的。
  3. 我還是覺得你可能想要做的事,如:
  4. 另外提醒實際測量一下計時器是做,而不是依靠我的猜測...

代碼TimerTask內:

public void iUpdateTimerLabel() 
{ 
//calculate : sign, sMin, sSec, sTenth  

// synchronized(Application.getEventLock()) 
    UiApplication.getUiApplication().invokeLater(
    new Runnable() { 
     @Override 
     public void run() { 
     lblSpotTime.setText(sign+sMin+":"+sSec+"."+sTenth+" "); 
     } 
    }); 
} 

您的​​調用可能足以防止炸燬,但它並不是真正的首選方法。如果Timer線程專門用於此目的,如果您願意,您可以用invokeAndWait()代替invokeLater()

其他人可能能夠闡明只持有UI鎖和實際上在UI線程上運行之間的區別,但我的猜測是後者強制invalidate(),而前者不。這可以解釋爲什麼你的標籤變化只是偶爾出現。

+0

你好Andersoj,我剛剛發佈我的代碼。你能指出我可能錯過了什麼嗎?謝謝。 – 2010-11-03 23:23:03

+0

我試過「invokeLater()」並得到相同的結果,那麼我可能需要測量計時器。非常感謝你的幫助。 – 2010-11-04 19:42:30

+0

@Tuyen Nguyen:讓我們知道你在找什麼。 – andersoj 2010-11-04 22:45:28