如何在Java中实现Timer类?

问题描述:

最近,我一直在开发一些android应用程序,我发现android.os.Handler类非常适合实现.NET定时器(我的意思是System.Windows.Forms.TimerSystem.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.Timercancel()之后无法重新启动。我知道你在说什么,“你为什么要在startTimer()方法中拨打cancel()?”如果我没有拨打cancel(),当定时器已经启动时,当我拨打startTimer()时,定时器将有2个任务在运行。

任何帮助将不胜感激。

+0

javax.swing.timer – Rishav

我发现有一类名为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