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

Tom*_*ski 3 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;
    }
Run Code Online (Sandbox Code Playgroud)

这个实现背后的想法是beatDetected()可以从外部事件调用,在这种情况下,下一个计时器滴答应该从那一刻起发生,即应该重置下一个任务的经过时间.但是,我只得到第一个滴答,从那时起,计时器就不起作用了.我不限于使用Timer类,任何可以解决上述场景的方法都可以.我正在使用postDelayed,但这段代码位于一个服务中,我真的不需要UI线程感知更新.

ina*_*ruk 10

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

如果您不需要超精确定时事件,则应使用Handler基于定时器的定时器.这里可以看到这样一个计时器的例子:重复一个延时的任务?.这种方法适用于活动和服务.

另请注意,如果设备进入睡眠模式,将暂停两个HandlerTimer基于计时器.如果这不是您所需要的,请使用AlarmManager(但请记住,AlarmManager错误使用可能会导致电池性能非常差).


重置Handler基于计时器:

 void resetRepeatingTask() {
     mHandler.removeCallbacks(mBeatDetector);
     mHandler.postDelayed(mBeatDetector, mInterval);         
 }
Run Code Online (Sandbox Code Playgroud)


Ian*_*anS 5

接受的答案不起作用(至少不适合我)。

一个简单的解决方案是使用 aTimer来触发 a 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);
Run Code Online (Sandbox Code Playgroud)

请注意,TimerTask每次重置计时器时都必须创建一个新的 - 您不能重复使用旧的。如果要保留状态,则需要让计时器任务运行单独的任务。