2012-07-18 58 views
11

请参阅@Yuri从此处发布的代码。 How to stop a timer after certain number of times。如果由于某种原因想要停止它,然后重新启动它。我该怎么去做呢?暂停计时器,然后继续计时

private final static int DELAY = 10000; 
    private final Handler handler = new Handler(); 
    private final Timer timer = new Timer(); 
    private final TimerTask task = new TimerTask() { 
     private int counter = 0; 
     public void run() { 
      handler.post(new Runnable() { 
       public void run() { 
        Toast.makeText(MainActivity.this, "test", Toast.LENGTH_SHORT).show(); 
       } 
      }); 
      if(++counter == 4) { 
       timer.cancel(); 
      } 

    //do some stuff in my app 
    //restart the timer again 

     } 
    }; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     timer.schedule(task, DELAY, DELAY); 

    } 

这是我试过的,但它一直在崩溃。

final int DELAY = 10000; 
     Timer timer; 
     MyTask task; 
     startManager Scanner; 
     Handler handler; 



     public class MyTask extends TimerTask { 

      @Override 
      public void run() { 
       handler.post(new Runnable() { 
        public void run() { 
         //do Stuff here 
         } 
     }); 
    } 
     public class startManager { 

      public startManager() { 
       handler = new Handler(); 
       timer = new Timer(); 
      } 

      public void start() { 

       timer.schedule(task, 0, DELAY); 
      } 

      public void cancel() { 

       timer.cancel(); 
       timer.purge(); 

      } 
     } 

    } 

@Override 
     public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.activity_main); 

Scanner = new startManager(); 
//do some stuff 
if (...) 
Scanner.cancel() 
//restart the timer and its task 
Scanner=new startManager(); 
     } 

回答

24

如果您已经取消了一个计时器,您不能重新启动它,您将不得不创建一个新的计时器。

看到这个answer,它包含一个视频和源代码我是如何做类似的。

基本上有两种方法:暂停和恢复

在暂停:

public void pause() { 
    this.timer.cancel(); 
} 

在简历:

public void resume() { 
    this.timer = new Timer(); 
    this.timer.schedule(aTask, 0, 1000); 
} 

这使得暂停/恢复的感知。

如果你的计时器基于应用程序的你可以考虑使用StatePattern

拳定义抽象状态的状态执行不同的操作:

abstract class TaskState { 
    public void run(); 
    public TaskState next(); 
} 

,并根据需要提供尽可能多的国家。关键是一个国家会把你引向另一个国家。

class InitialState extends TaskState { 
    public void run() { 
     System.out.println("starting..."); 
    } 
    public TaskState next() { 
     return new FinalState(); 
    } 
} 
class FinalState extends TaskState { 
    public void run() { 
     System.out.println("Finishing..."); 
    } 
    public TaskState next(){ 
     return new InitialState(); 
    } 
} 

然后你改变你的计时器的状态。

Timer timer = new Timer(); 
TaskState state = new InitialState(); 

timer.schedule(new TimerTask() { 
    public void run() { 
      this.state.run(); 
      if(shouldChangeState()) { 
       this.state = this.state.next(); 
      } 
    } 
}, 0, 1000); 

最后,如果你需要的是执行同样的事情,但以不同的速度,你可以考虑使用TimingFramework。它有点复杂,但让我们做一些很酷的动画,通过允许某些组件的绘制以不同的速率发生(而不是线性)

+0

我试图取消它,然后创建一个新的计时器,但它仍然导致它崩溃。你能解释为什么我需要处理程序吗?我可以把它拿出来吗?其实,我没有经理就先试了一下。 – jimmyC 2012-07-18 21:43:51

+0

处理程序允许您发送和处理与线程的MessageQueue关联的消息和可运行对象。每个Handler实例都与单个线程和该线程的消息队列相关联。当您创建一个新的处理程序时,它将绑定到正在创建它的线程的线程/消息队列 - 此后,它将消息和可运行消息传递到该消息队列,并在消息出来时执行它们队列。 – SALMAN 2012-07-18 21:48:24

+0

我遇到了一个问题,我认为当旧的计时器没有完全停止时,它会产生太多的新计时器。例如,我取消了一个计时器,但是如果任务正在运行,它需要等到它结束。然后(在我的代码中)取消它之后(在较早的定时器实际完成之前),我启动一个新的startManager并创建一个新的定时器。有没有一种方法可以确保在旧任务完全停止运行之前计时器不会启动。 – jimmyC 2012-07-19 16:19:14

1

设想出来,这是因为我没有初始化任务startManager()