В последнее время я разрабатываю некоторые приложения для Android, и я обнаружил, что класс android.os.Handler
очень подходит для реализации .NET Timer (под этим я имею в виду System.Windows.Forms.Timer
и System.Timers.Timer
).Как реализовать класс Timer в Java?
Если вы не знаете, что такое таймер .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();
}
}
И это вышло ок. Кроме того, этот работает в потоке пользовательского интерфейса, что означает, что я могу использовать его для изменения графического материала. (Я в основном использую таймеры для этих вещей)
Однако это работает только для 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()
, таймер будет работать 2 задачи, когда я вызову startTimer()
, когда таймер уже запущен.
Любая помощь будет оценена по достоинству.
javax.swing.timer – Rishav