Refer to the code that @Yuri posted from here. How to stop a timer after certain number of times . If I wanted to stop it because of some condition and then restart it again. How would I go about doing it?
参考@Yuri从这里发布的代码。如何在一定次数后停止计时器。如果我想因为某些情况而停止它,然后重新启动它。我该怎么做呢?
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);
}
Here's what I've tried , but it keeps crashing on me.
这是我试过的,但它一直砸在我身上。
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();
}
3 个解决方案
#1
24
If you have already canceled one timer, you can't re-start it, you'll have to create a new one.
如果您已经取消了一个计时器,您不能重新启动它,您将不得不创建一个新的计时器。
See this answer, it contains a video and the source code how I did something similar.
看看这个答案,它包含一个视频和源代码,我是如何做类似的事情的。
Basically there are two method: pause and resume
基本上有两种方法:暂停和恢复
In pause:
暂停:
public void pause() {
this.timer.cancel();
}
In resume:
简历:
public void resume() {
this.timer = new Timer();
this.timer.schedule( aTask, 0, 1000 );
}
That makes the perception of pause/resume.
这使得人们对暂停/恢复的看法。
If your timers perform different actions based on the state of the application you may consider use the StatePattern
如果您的计时器根据应用程序的状态执行不同的操作,您可以考虑使用StatePattern
Fist define a abstract state:
首先定义一个抽象状态:
abstract class TaskState {
public void run();
public TaskState next();
}
And provide as many states as you like. The key is that one state leads you to another.
并提供尽可能多的状态。关键是,一个州把你引向另一个州。
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();
}
}
And then you change the state in your timer.
然后你改变计时器的状态。
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 );
Finally, if what you need is to perform the same thing, but at different rates, you may consider using the TimingFramework. It is a bit more complex but let's you do cool animations, by allowing the painting of certain component take place at different rates ( instead of being linear )
最后,如果您需要执行相同的操作,但是速度不同,您可以考虑使用TimingFramework。它有点复杂,但是让我们来做一些很酷的动画,通过允许以不同的速率(而不是线性)绘制某些部件
#2
1
There appears to be no way to do this: http://docs.oracle.com/javaee/6/api/javax/ejb/Timer.html
似乎没有办法做到这一点:http://docs.oracle.com/javaee/6/api/javax/ejb/Timer.html
You could likely cancel the timer, then create a new one.
您可以取消计时器,然后创建一个新的计时器。
#3
1
FIgured it out, it was because I didn't initialize the task in startManager()
因为我没有在startManager()中初始化任务
#1
24
If you have already canceled one timer, you can't re-start it, you'll have to create a new one.
如果您已经取消了一个计时器,您不能重新启动它,您将不得不创建一个新的计时器。
See this answer, it contains a video and the source code how I did something similar.
看看这个答案,它包含一个视频和源代码,我是如何做类似的事情的。
Basically there are two method: pause and resume
基本上有两种方法:暂停和恢复
In pause:
暂停:
public void pause() {
this.timer.cancel();
}
In resume:
简历:
public void resume() {
this.timer = new Timer();
this.timer.schedule( aTask, 0, 1000 );
}
That makes the perception of pause/resume.
这使得人们对暂停/恢复的看法。
If your timers perform different actions based on the state of the application you may consider use the StatePattern
如果您的计时器根据应用程序的状态执行不同的操作,您可以考虑使用StatePattern
Fist define a abstract state:
首先定义一个抽象状态:
abstract class TaskState {
public void run();
public TaskState next();
}
And provide as many states as you like. The key is that one state leads you to another.
并提供尽可能多的状态。关键是,一个州把你引向另一个州。
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();
}
}
And then you change the state in your timer.
然后你改变计时器的状态。
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 );
Finally, if what you need is to perform the same thing, but at different rates, you may consider using the TimingFramework. It is a bit more complex but let's you do cool animations, by allowing the painting of certain component take place at different rates ( instead of being linear )
最后,如果您需要执行相同的操作,但是速度不同,您可以考虑使用TimingFramework。它有点复杂,但是让我们来做一些很酷的动画,通过允许以不同的速率(而不是线性)绘制某些部件
#2
1
There appears to be no way to do this: http://docs.oracle.com/javaee/6/api/javax/ejb/Timer.html
似乎没有办法做到这一点:http://docs.oracle.com/javaee/6/api/javax/ejb/Timer.html
You could likely cancel the timer, then create a new one.
您可以取消计时器,然后创建一个新的计时器。
#3
1
FIgured it out, it was because I didn't initialize the task in startManager()
因为我没有在startManager()中初始化任务