13

问题 我在使用 android 开发时遇到停止计时器的问题。

停止计时器时,计时器已经为空。

timer.cancel();然后我将定时器初始化移动到一个方法之外,就像 TimerTask 一样,它解决了 null 问题,但在调用它时仍然不会取消。

下面的代码是停止录制时计时器已经为空的示例。

定时器任务

TimerTask在类内部但在方法和下面的代码之外初始化......

private TimerTask task = new TimerTask() {
    @Override
    public void run() {
      Log.e("TRACK_RECORDING_SERVICE","Timer Running");
    }
  };

定时器和定时器启动

然后我有一个 startRecroding 方法,当我想启动计时器时调用它......

public void startRecording(){
     timer = new Timer("Message Timer");
     timer.scheduleAtFixedRate(this.task, 0, 1000);
 }

定时器停止

然后,当我想停止计时器时,我会调用以下方法...

public void stopRecording() {
     if (timer != null) {
         timer.cancel();
         timer = null;
     } else {
         Log.e("TRACK_RECORDING_SERVICE","Timer already null.");
     }
 }

任何帮助将非常感激。

4

8 回答 8

22
timer = new Timer("Message Timer"); 

这里你的对象timer不是一个static所以timer.cancel();会取消 Timer 类的另一个实例。我建议你在类的顶部创建一个 Timer Class 的静态实例变量,如下所示,

private static Timer timer;
于 2012-07-16T10:49:01.460 回答
3

在 run() 方法中,检查计时器是否为空

private TimerTask task = new TimerTask() {
@Override
public void run() {
if (timer == null)
	cancel();
...
}

取消操作。

于 2014-12-21T14:37:23.397 回答
2

好的,所以问题出在实例化中,而不是定时器的实际停止。

每次我打电话:

timer = Timer()
timer!!.scheduleAtFixedRate(object : TimerTask() {
    override fun run() {
       //something  
    }
}, delay, period)

它创建了另一个实例,因此旧实例仍在某个地方运行,无法阻止它。

所以我只是确保在计时器为空时实例化它,这样之前的实例就不会被推送并仍在后台运行。

if(timer == null) {
    timer = Timer()
    timer!!.scheduleAtFixedRate(object : TimerTask() {
        override fun run() {
            // something
        }
    }, delay, period)
}

然后只需取消它并将其设置为空。

fun stopTimer() {
    if (timer != null) {
        timer!!.cancel()
        timer!!.purge()
        timer = null
    }
}
于 2019-08-16T18:21:00.860 回答
1
if(waitTimer != null) {
   waitTimer.cancel();
   waitTimer.purge()
   waitTimer = null;
}
于 2012-07-16T10:57:04.950 回答
1

我知道已经很晚了,但我在我的项目中也遇到了这个问题,希望我的解决方案能给人们一些想法。我在我的项目中所做的如下:

Handler handler = new Handler();
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
           //TODO Update UI
        }
    };

    public void stopTimer() {
        if (timer != null) {
            handler.removeCallbacks(runnable);
            timer.cancel();
            timer.purge();
            timer = null;
        }
    }

   public startTimer() {
            timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    handler.post(runnable);
                }
            }, 0, 100);
       }

我认为以前的答案中遗漏的是removeCallbacks

于 2015-12-14T05:23:49.823 回答
0

试试这个例子......

     TimerTask mTimerTask;
    final Handler handler = new Handler();
    Timer t = new Timer();  
    int nCounter = 0;

//function for start timer
 public void doTimerTask()
    {

        mTimerTask = new TimerTask() 
        {
                public void run() 
                {
                        handler.post(new Runnable() 
                        {
                                public void run()
                                {

                                      nCounter++:       
                                    //your code
                                    .....
                                    ......

                                }
                       });
                }};

            // public void schedule (TimerTask task, long delay, long period) 
            t.schedule(mTimerTask,0,50);  // 

         }

         //function for stop timer
public void stopTimerTask(){

       if(mTimerTask!=null){

          Log.d("TIMER", "timer canceled");
          mTimerTask.cancel();
          nCounter = 0; 

     }

}    

//使用上面两个函数来启动和停止定时器。

于 2012-07-16T12:12:06.850 回答
0

以防万一有人仍然来这里寻找解决此问题的方法,这是我的经验。

我正在服务中运行计时器。

startForegroundService(mServiceIntent);

timer = new Timer();

当你刷新一个服务时,你不一定要先取消它,你只需调用 startForegroundService(mServiceIntent); 再次。如果您在刷新服务之前不取消定时器,即使您在刷新的新服务中停止定时器,原始定时器仍会在后台运行并调用方法。

总而言之,在刷新或更新后台任务之前停止计时器。我希望它可以帮助某人。

于 2018-09-19T01:18:46.620 回答
0

虽然这是一个老问题,但我已经找到了一个简单的解决方案。

var timeTaskInstance : TimerTask ?= null

val task: TimerTask = object : TimerTask() {
      override fun run() {
           timeTaskInstance = this
           Log.e("TRACK_RECORDING_SERVICE", "Timer Running")
      }
 }

现在从任何地方取消计时器:

timeTaskInstance?.cancel()
于 2021-04-30T09:57:54.213 回答