带有重置选项的Android java.util.Timer

时间:2011-12-06 18:17:32

标签: java android timer repeat

我有一个场景,我需要以特定的间隔运行某个任务,但是,我希望能够重置/重新启动计时器而不重新实例化。这是我的代码,以便更好地理解。

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线程感知更新。

2 个答案:

答案 0 :(得分:10)

在Android设备上使用单独的线程进行计时器被认为是一种不太好的做法。那是因为在大多数情况下你会浪费资源。

如果您不需要超精确的计时事件,则应使用基于Handler的计时器。这里可以看到这样一个计时器的例子:Repeat a task with a time delay?。这种方法适用于活动和服务。

另请注意,如果设备进入睡眠模式,基于HandlerTimer的计时器将暂停。如果这不是您所需要的,请使用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 - 您无法重复使用旧计时器。如果要保留状态,则需要让计时器任务运行单独的任务。