最近,我一直在开发一些Android应用程序,我发现android.os.Handler
类非常适合实现.NET Timer(我的意思是System.Windows.Forms.Timer
和System.Timers.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()
。而且我知道你在说什么,“为什么你用cancel()
方法拨打startTimer()
?”如果我不调用cancel()
,当计时器已经启动时,当我调用startTimer()
时,计时器将运行2个任务。
任何帮助将不胜感激。
答案 0 :(得分:0)
来自Timer类的cancel()
方法
终止此计时器,丢弃当前计划的任何任务。是否 不干扰当前正在执行的任务(如果存在)。一旦 计时器已终止,其执行线程正常终止, 并且不再安排任何任务。
请注意,在计时器的run方法中调用此方法 这个计时器调用的任务绝对保证了 正在进行的任务执行是最后一次执行任务 由此计时器执行。
这种方法可以重复调用;第二次和后续的电话 没有效果。
所以,Timer的内部线程是一次性的,你需要实例化一个新的Timer
对象
您可以查看Timer类的原始源代码,以了解(或根据需要复制)它的实际工作方式
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Timer.java
答案 1 :(得分:0)
我发现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);
}
}
它有一个非常简单的界面。非常容易使用。