我有一个场景,我需要以特定的间隔运行某个任务,但是,我希望能够重置/重新启动计时器而不重新实例化。这是我的代码,以便更好地理解。
private TimerTask beatTask = new TimerTask() {
@Override
public void run() {
beatDetected();
}
};
public void beatDetected() {
timeoutTimer.cancel();
// handle my stuff and restart the timer.
timeoutTimer.schedule(beatTask, 2000);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
(timeoutTimer = new Timer()).schedule(beatTask, 2000);
return Service.START_STICKY;
}
这种实现背后的想法是可以从外部事件调用beatDetected()
,在这种情况下,下一个计时器滴答应该从那一刻起发生,即应该重置下一个任务的经过时间。但是,我只得到第一个滴答,从那时起,计时器就不起作用了。
我不限于使用Timer类,任何可以解决上述场景的方法都可以。我正在使用postDelayed,但这段代码位于一个服务中,我真的不需要UI线程感知更新。
答案 0 :(得分:10)
在Android设备上使用单独的线程进行计时器被认为是一种不太好的做法。那是因为在大多数情况下你会浪费资源。
如果您不需要超精确的计时事件,则应使用基于Handler
的计时器。这里可以看到这样一个计时器的例子:Repeat a task with a time delay?。这种方法适用于活动和服务。
另请注意,如果设备进入睡眠模式,基于Handler
和Timer
的计时器将暂停。如果这不是您所需要的,请使用AlarmManager
(但请注意,错误地使用AlarmManager
可能会导致电池性能非常糟糕。)
重新设定基于Handler
的计时器:
void resetRepeatingTask() {
mHandler.removeCallbacks(mBeatDetector);
mHandler.postDelayed(mBeatDetector, mInterval);
}
答案 1 :(得分:3)
接受的答案不起作用(至少不适合我)。
一个简单的解决方案使用Timer
来触发TimerTask
,这可以轻松重置。
Log.d(TAG, "Restarting timer");
if (timer != null) {
timer.cancel();
}
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
Log.d(TAG, "Run the task");
}
}, 1000);
请注意,每次重置计时器时都必须创建一个新的TimerTask
- 您无法重复使用旧计时器。如果要保留状态,则需要让计时器任务运行单独的任务。