如何在Java中实现Timer类?

时间:2015-08-03 12:51:14

标签: java timer

最近,我一直在开发一些Android应用程序,我发现android.os.Handler类非常适合实现.NET Timer(我的意思是System.Windows.Forms.TimerSystem.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个任务。

任何帮助将不胜感激。

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);
    }
}

它有一个非常简单的界面。非常容易使用。