如何在Java中实现Timer类?
最近,我一直在开发一些android应用程序,我发现android.os.Handler
类非常适合实现.NET定时器(我的意思是System.Windows.Forms.Timer
和System.Timers.Timer
)。如何在Java中实现Timer类?
如果你不知道什么是.NET定时器,它是一个可以停止,随时启动的定时器,它的间隔可以随时更改。
所以我做了以下内容:
import android.os.Handler;
public class Timer {
private Handler handler;
private boolean paused;
private int interval;
private Runnable task = new Runnable() {
@Override
public void run() {
if (!paused) {
runnable.run();
Timer.this.handler.postDelayed (this, interval);
}
}
};
private Runnable runnable;
public int getInterval() {
return interval;
}
public void setInterval(int interval) {
this.interval = interval;
}
public void startTimer() {
paused = false;
handler.postDelayed (task, interval);
}
public void stopTimer() {
paused = true;
}
public Timer (Runnable runnable, int interval, boolean started) {
handler = new Handler();
this.runnable = runnable;
this.interval = interval;
if (started)
startTimer();
}
}
而且它出来确定。此外,这一个在UI线程上运行,这意味着我可以使用它来改变图形的东西。 (我主要使用这些东西的计时器)
但是,这只适用于android虽然。如果我想制作一个“传统”的Java程序,我必须使用JDK中的东西。所以,我试过如下:
import java.util.Timer;
import java.util.TimerTask;
public class DotNetTimer {
private Timer timer;
private boolean paused;
private int interval;
private TimerTask task = new TimerTask() {
@Override
public void run() {
if (!paused)
runnable.run();
}
};
public Runnable runnable;
public int getInterval() {
return interval;
}
public void setInterval(int interval) {
this.interval = interval;
if (!paused) {
timer.cancel();
timer.scheduleAtFixedRate(task, interval, interval);
}
}
public void startTimer() {
timer.cancel();
timer.scheduleAtFixedRate(task, 0, interval);
}
public void stopTimer() {
paused = true;
}
public DotNetTimer (Runnable runnable, int interval, boolean started) {
timer = new Timer();
this.runnable = runnable;
this.interval = interval;
if (started) {
paused = false;
startTimer();
}
}
}
我使用此代码来测试它:
import static java.lang.System.out;
public class MyTestingClass {
static DotNetTimer timer;
public static void main(String[] args) {
Runnable r = new Runnable() {
int count = 0;
@Override
public void run() {
if (count < 5) {
count++;
out.println("Hello" + count);
} else {
timer.stopTimer();
}
}
};
timer = new DotNetTimer (r, 2000, true);
}
}
然而,IllegalStateException
在开始计时方法被抛出。我对此做了一些研究,发现java.util.Timer
在cancel()
之后无法重新启动。我知道你在说什么,“你为什么要在startTimer()
方法中拨打cancel()
?”如果我没有拨打cancel()
,当定时器已经启动时,当我拨打startTimer()
时,定时器将有2个任务在运行。
任何帮助将不胜感激。
我发现有一类名为Android的Handler
可与延迟执行代码。所以我利用这个类创建了一个计时器!
import android.os.Handler;
import android.support.annotation.NonNull;
import android.widget.TextView;
public class Timer implements Comparable<Timer> {
private Handler handler;
private boolean paused;
private TextView text;
private int minutes;
private int seconds;
private final Runnable timerTask = new Runnable() {
@Override
public void run() {
if (!paused) {
seconds++;
if (seconds >= 60) {
seconds = 0;
minutes++;
}
text.setText (Timer.this.toString());
Timer.this.handler.postDelayed (this, 1000);
}
}
};
@Override
public String toString() {
if (Integer.toString (seconds).length() == 1) {
return minutes + ":0" + seconds;
} else {
return minutes + ":" + seconds;
}
}
public void startTimer() {
paused = false;
handler.postDelayed (timerTask, 1000);
}
public void stopTimer() {
paused = true;
}
public void resetTimer() {
stopTimer();
minutes = 0;
seconds = 0;
text.setText (toString());
}
public Timer (TextView text) {
this.text = text;
handler = new Handler();
}
public Timer (TextView text, String parseString) {
this (text);
String[] splitString = parseString.split (":");
minutes = Integer.parseInt (splitString[0]);
seconds = Integer.parseInt (splitString[1]);
}
@Override
public int compareTo(@NonNull Timer another) {
int numberOfSeconds = seconds + minutes * 60;
int anotherNumberOfSeconds = another.seconds + another.minutes * 60;
return ((Integer)numberOfSeconds).compareTo (anotherNumberOfSeconds);
}
}
它有一个非常简单的界面。非常容易使用。
从Timer类
cancel()
方法终止此计时器,丢弃所有当前已安排的任务。 是否不干扰当前正在执行的任务(如果存在)。一旦 计时器被终止,它的执行线程将优雅地终止, 并且不能在其上安排更多任务。注意,从由此计时器调用的计时器 任务的run方法中调用此方法绝对保证的 持续执行任务是,将永远是此计时器进行 最后一次执行任务。
该方法可能会重复调用;第二个和后续呼叫 不起作用。
所以,定时器的内螺纹是一次性的,你需要实例化一个新的Timer
对象
您可以检查Timer类的原始源代码来了解(或复制,如你所愿)如何真正作品
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Timer.java
javax.swing.timer – Rishav