2015-08-03 5 views
1

В последнее время я разрабатываю некоторые приложения для 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(), когда таймер уже запущен.

Любая помощь будет оценена по достоинству.

+0

javax.swing.timer – Rishav

ответ

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

И он имеет очень простой интерфейс. Очень проста в использовании.

0

От cancel() метода Таймер класса

Завершает этот таймер, отбрасывая все текущие задачи по расписанию. не мешает выполнению текущей задачи (если она существует). После того, как таймер был прерван, его исполнительный поток прекращается изящно, , и на нем больше не может быть запланировано никаких задач.

Обратите внимание, что вызов этого метода внутри методы выполнения таймера задачи, которая была вызвана с помощью этого таймера абсолютно гарантирует, что продолжающееся выполнение задачи последнее выполнение задачи, которая когда-либо будет в исполнении этого таймером.

Этот метод можно вызывать повторно; второй и последующие вызовы не влияют.

так, внутренняя резьба таймера является один выстрел, вам нужно создавать новый Timer объект

Вы можете проверить исходный код класса Timer, чтобы понять (или повторить, как вы хотите), как это на самом деле работы

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Timer.java

Смежные вопросы