我正在为BlackBerry编写一个秒表应用程序(类似于BlackBerry内置的StopWatch)。有一个显示当前时间的计时器标签,格式为MM:SS:T(分钟,秒,十分之一秒)。使用TimerTask每100毫秒刷新一次标签。
应用程序运行良好且时间显示正确,但是,有些时刻定时器标签不会以预定间隔(每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+" ");
}
}
答案 0 :(得分:2)
首先是测量它...记录你的时间任务开始和结束时的时间戳,看看它是否真的是TimerTask
真正的问题。有了这些,我发现的一些事情是,
Timer
实例?我不知道它是否被指定为这样,但是任务可能都在一个线程上运行,所以如果另一个任务妨碍了,你的任务可能无法按照指定的时间间隔运行。TimerTask
是否与UI事件循环正确同步(即,是否使用正确的runLater()
或黑莓UI提供的任何方法更新标签)?如果您不这样做,UI事件循环可能不会注意到您已更改标签。我认为在Blackberry上,正确的是invokeLater()
或者invokeAndWait()
,这取决于你想要实现的目标。在代码发布后编辑:
一些有用且相关的资源是here。
schedule()
调用在它自己的Runnable
内...你不需要它,但也许你的应用程序是出于某种原因我无法看到它。如果你认为你正在为计时器创建一个显式线程,那你就不是。你可以创建Timer
并从任何应用程序线程设置它来调用schedule()
。 Timer
包含一个将执行此工作的强制线程,并且引入Yet Another Thread可能是多余且令人困惑的。在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+" ");
}
});
}
你的synchronized
电话可能足以防止事情发生,但这并不是首选方式。如果Timer
主题专用于此单一目的,则如果您愿意,可以将invokeLater()
替换为invokeAndWait()
。
其他人可能能够阐明仅仅持有UI锁和实际在UI线程上运行之间的区别,但我的猜测是后者强制invalidate()
,而前者不强制。{{1}}。这可以解释为什么您的标签更改只会偶尔出现。