Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/211.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android中的计时器未停止_Android - Fatal编程技术网

Android中的计时器未停止

Android中的计时器未停止,android,Android,问题 在android中开发时,我无法停止计时器 计时器在停止时已为空 然后,我将计时器初始化移到方法之外,就像TimerTask一样,它解决了null问题,但在timer.cancel()时仍然不会取消被调用 下面的代码是计时器停止录制时已为空的示例 TimerTask MyTimerTask在类内部但在方法外部初始化,下面的代码 private TimerTask task = new TimerTask() { @Override public void run() {

问题 在android中开发时,我无法停止计时器

计时器在停止时已为空

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

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

TimerTask

My
TimerTask
在类内部但在方法外部初始化,下面的代码

private TimerTask task = new TimerTask() {
    @Override
    public void run() {
      Log.e("TRACK_RECORDING_SERVICE","Timer Running");
    }
  };
定时器和定时器启动

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

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.");
     }
 }
计时器停止

然后,当我想停止计时器时,我调用下面的方法

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.");
     }
 }
任何帮助都将不胜感激

timer = new Timer("Message Timer"); 
在这里,您的对象
timer
不是一个
静态的
所以
timer.cancel()将取消计时器类的另一个实例。我建议您在类的顶部创建Timer类的静态实例变量,如下所示

private static Timer timer;
试试这个例子

     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; 

     }

}    
//将以上两个函数用于启动和停止计时器。

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

private TimerTask task=new TimerTask(){
@凌驾
公开募捐{
如果(计时器==null)
取消();
...

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

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);
       }

我认为在以前的回答中遗漏的是删除回调

以防万一,如果有人仍然来这里寻找这个问题的解决方案,以下是我的经验

我正在服务中运行计时器

startForegroundService(mServiceIntent);

timer = new Timer();
刷新服务时,不必先取消它,只需再次调用startForegroundService(MSServiceIntent)。 如果在刷新服务之前没有取消计时器,则即使在刷新的新服务中停止计时器,原始计时器仍在后台运行并调用方法

总之,在刷新或更新后台任务之前,请停止计时器。
我希望它能帮助一些人。

好的,所以问题在于实例化,而不是计时器的实际停止

每次我打电话:

timer = Timer()
timer!!.scheduleAtFixedRate(object : TimerTask() {
    override fun run() {
       //something  
    }
}, delay, period)
它创建了另一个实例,因此旧实例仍在某处运行,无法停止

因此,我只是确保在计时器为null时实例化它,这样以前的实例就不会被推送,并且仍然在后台运行

if(timer == null) {
    timer = Timer()
    timer!!.scheduleAtFixedRate(object : TimerTask() {
        override fun run() {
            // something
        }
    }, delay, period)
}
然后取消它并将其设置为null

fun stopTimer() {
    if (timer != null) {
        timer!!.cancel()
        timer!!.purge()
        timer = null
    }
}

虽然这是个老问题,但我找到了一个简单的解决办法

var timeTaskInstance : TimerTask ?= null

val task: TimerTask = object : TimerTask() {
      override fun run() {
           timeTaskInstance = this
           Log.e("TRACK_RECORDING_SERVICE", "Timer Running")
      }
 }
现在从任意位置取消计时器:

timeTaskInstance?.cancel()

您是否尝试过task.cancel()后跟timer.purge()?我创建了静态实例,然后它也不会停止是的,我也创建了静态实例,它也不会停止:)我看不出引用静态有什么帮助。
cancel()
是在
定时器
引用的
定时器
上调用的,为什么要为另一个实例调用它呢?我不知道,但它可以工作。可能是因为
静态
使该类的属性唯一,即该类上的所有实例只有一个该属性的实例。但是,我不知道为什么会有多个实例它的一个实例…它对我不起作用。即使我只创建了一个实例,它也不起作用。