I have a method called timer that I run everytime a user inputs something and the timer is scheduled for a minute, but I want the timer to cancel if the user enters something in less than a minute and then recall itself so the whole process happens again. My methods are below:
Input method
public static String run(){
timer(); //runs everytime I call run()
String s = input.nextLine();
return s;
}
Timer method
public static void timer() {
TimerTask task = new TimerTask() {
public void run() {
System.out.println("Times up");
}
};
long delay = TimeUnit.MINUTES.toMillis(1);
Timer t = new Timer();
t.schedule(task, delay);
}
method run() keeps getting called everytime someone inputs something so timer keeps getting called but that doesn't stop the previous timers though, I want the timer to stop, then recall itself so that problem doesn't exist. Anyone know a way?
The TimerTask class has a method called cancel() which you can call to cancel a pending timer.
In your code, you will probably need to modify your timer() function to return a reference to the newly created TimerTask object, so that you can later call cancel().
Related
I am new to programming and I am doing one android application on which I have one requirement where I need to monitor some logs for the 30s. I am using a timer task but what is happening, if the 30s are over and the run method executed once it is terminated the timer task not repeating.
Here is my code:
connectivityTimerTask = new ConnectivityTimerTask();
timer = new Timer(true);
//timer = new Timer(); // tried with this but it is not working
timer.schedule(connectivityTimerTask,30 * 1000);
TimerTask:
public class ConnectivityTimerTask extends TimerTask {
#Override
public void run() {
Log.error("----- ACK NotReceived -----" + System.currentTimeMillis());
//resetMonitor(); using this method I am setting the timer again
}
}
I want to know what's the best practice for scheduling repeating time.
Am I using the correct way? Can I use the resetMonitor() method?
Instead of of schedule(), You can use Timer task that can be scheduled at fixed rate with scheduleAtFixedRate,
int THIRTY_SECONDS = 30 * 1000;
Timer mTimer = new Timer();
mTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// do whatever you want every 30s
Log.e("TAG", "----- ACK NotReceived -----" + System.currentTimeMillis());
}
}, 0, THIRTY_SECONDS);
Whenever you want to stop the timer call timer.cancel()
The line
timer.schedule(connectivityTimerTask,30 * 1000)
runs your task after a 30s delay and once the task completes, the timer's job is done.
If you want to keep running your task at periodic intervals, you have to also specify an interval period
schedule (TimerTask task, long delay, long period) // "period" specifies how often you want to run the task
Read the documentation here.
To repeatedly run some code after a set period of time, use a Runnable with a Handler like so
Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
// do your logging
handler.postDelayed(this, 30000);
}
};
handler.post(runnable); // or handler.postDelayed(runnable, 30000) if you want it to wait 30s before starting initially
To cancel
handler.removeCallbacks(runnable);
In a run method of a TimerTask object, How can I submit the timerTask itself to another Timer.
When the timerTask is running, I should do a judge and decide whether it can do some work. If it not meet the condition, I should cancel it and put it to another Timer.
Code of my TimerTask is like this:
#Override
public void run() {
try {
if (flag) {
// do something
} else {
new Timer().schedule(this, 1000 * 60);
}
} catch (Exception e) {
e.printStackTrace();
}
Will it work?
You should only use one Timer and then monitor the condition from external, for example from a Thread, a Runnable or another Timer. Then stop, cancel, re-assign, start the timer as necessary from your external monitor.
Here's a TimerTask:
public class OurTask extends TimerTask {
#Override
public void run() {
// Do something
}
}
And here's the monitor:
public Monitor implements Runnable() {
private Timer mTimerToMonitor;
public Monitor(Timer timerToMonitor) {
this.mTimerToMonitor = timerToMonitor;
}
#Override
public void run() {
while (true) {
if (!flag) {
// Cancel the timer and start a new
this.mTimerToMonitor.cancel();
this.mTimerToMonitor = new Timer();
this.mTimerToMonitor.schedule(...);
}
// Wait a second
Thread.sleep(1000);
}
}
}
Note that in practice your Monitor should also be able to get canceled from outside, currently it runs infinitely.
And this is how you could call it:
Timer timer = new Timer();
timer.schedule(new OurTask(), ...);
Thread monitorThread = new Thread(new Monitor(timer));
monitorThread.start();
Also note that instead of using Runnable, Timer and Thread it could be worth taking a look into the new Java 8 stuff, especially the interface Future and classes implementing it.
I'm making an Android app that turns on/off the flash light after a specified interval, by the user. It works well except when the Timer object is re-created after calling the .cancel() method for the second time, it crashes the app every time.
Here's the initialization part:
Timer timer; //variable of Timer class
TimerTask timerTask; //variable of TimerTask class
And here's the method that is called when the button responsible to turn blinking on/off is pressed:
blink.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
delay = Integer.valueOf(startDelay.getText().toString());
gap = Integer.valueOf(blinkDelay.getText().toString());
if(!isBlinking) { //isBlinking is a boolean to know whether to stop or re-start timer
timer = new Timer(); //I'm creating an object of Timer class every time.
isBlinking = true;
timer.schedule(timerTask, delay, gap);
}
else{
isBlinking = false;
stoptimertask(); //this will cancel the 'timer' and make it null.
}
}
});
The 'stoptimertask()' method from above code has:
public void stoptimertask() {
//stop the timer, if it's not already null
if (timer != null) {
timer.cancel();
timer = null;
}
}
I'm setting the 'timertask' variable of TimerTask class from the method shown below. It is called in the onCreate() method of the main activity:
public void initializeTimerTask() {
timerTask = new TimerTask() { //This is passed as the first argument to the timer.schedule() method
public void run() {//Basically turns on/off flash. Works well.
if(!state) {
turnOnFlash();
state = true;
}
else {
turnOffFlash();
state = false;
}
}
};
My question is that why does the app crash when I press the blink button the third time?
When it is pressed for the first time, isBlinking is false, so the if block executes creating a new object of the Timer class and starting the timer.
When it is pressed for the second time, stoptimertask() is called which cancels the timer and sets timer variable to null.
When it is pressed again for the third time with different values for delay and gap, a new object of Timer class should be created, but the application crashes unexpectedly with a "Unfortunately the app has stopped" error.
Where am I going wrong?
You will have to purge as well.
timer.cancel();
timer.purge();
Don't forget to purge after cancel.
Your code must be for stoptimertask() method.
public void stoptimertask() {
//stop the timer, if it's not already null
if (timer != null) {
timer.cancel();
timer.purge();
timer = null;
}
}
Related Link:
Android timer? How-to?
How to set a timer in android
UPDATE:
Since Timer creates a new thread, it may be considered heavy,
if all you need is to get is a call back while the activity is running a Handler can be used in conjunction with this link
How to set a timer in android
How do I make my Timer Task run more than once? This is really bothering me..
timer = new Timer();
timer.schedule(new Client(), 1000);
public void run() {
try {
System.out.println("sent data");
socketOut.write(0);
} catch (Exception e) {
// disconnect client on their side
Game.destroyGame();
timer.cancel();
timer.purge();
}
}
I want this timer to run for an infinite amount of time until the Exception occurs.
When the Javadoc says that it repeats with a specific delay, the delay is the initial delay before the TimerTask starts and not for how long the TimerTask will run. You can repeat the task every period milliseconds. Look at the schedule method. Below is a simple example that repeats every 2 seconds, indefinitely. In the example, the call:
timer.schedule(new RemindTask(seconds), 0, seconds * 1000);
tells timer to run the RemindTask every seconds seconds (*1000 because the time here is really in miliseconds), with an initial delay of 0 - i.e. start the RemindTask right away and then keep repeating at regular intervals.
import java.util.Timer;
import java.util.TimerTask;
public class Main {
static Timer timer;
static int i = 0;
class RemindTask extends TimerTask {
private int seconds;
public RemindTask(int seconds) {
this.seconds = seconds;
}
public void run() {
i+= seconds ;
System.out.println(i + " seconds!");
}
}
public Main(int seconds) {
timer = new Timer();
timer.schedule(new RemindTask(seconds), 0, seconds * 1000);
}
public static void main(String args[]) {
new Main(2);
System.out.format("Task scheduled.%n");
}
}
Looks like to me you're running a GUI program (I'm assuimg SWING, because your other question you were using SWING). So here's a bit of advice. Use a javax.swing.Timer for Swing program.
"How do I make my Timer Task run more than once? "
javax.swing.Timer has methods .stop() and .start() and .restart(). A basic implementation of the Timer object is something like this
Timer timer = new Timer(delay, new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
// do something
}
});
timer.start();
You can do anything you want in the actionPerformed and it will fire an event every how many ever milliseconds you provide to the delay. You can have a button call .start() or .stop()
See this answer for a simple implementation of Timer imitating a sort of stop watch for a Boggle game
I am using java.util.Timer class and I am using its schedule method to perform some task, but after executing it for 6 times I have to stop its task.
How should I do that?
Keep a reference to the timer somewhere, and use:
timer.cancel();
timer.purge();
to stop whatever it's doing. You could put this code inside the task you're performing with a static int to count the number of times you've gone around, e.g.
private static int count = 0;
public static void run() {
count++;
if (count >= 6) {
timer.cancel();
timer.purge();
return;
}
... perform task here ....
}
Either call cancel() on the Timer if that's all it's doing, or cancel() on the TimerTask if the timer itself has other tasks which you wish to continue.
You should stop the task that you have scheduled on the timer:
Your timer:
Timer t = new Timer();
TimerTask tt = new TimerTask() {
#Override
public void run() {
//do something
};
};
t.schedule(tt,1000,1000);
In order to stop:
tt.cancel();
t.cancel(); //In order to gracefully terminate the timer thread
Notice that just cancelling the timer will not terminate ongoing timertasks.
Terminate the Timer once after awake at a specific time in milliseconds.
Timer t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
System.out.println(" Run spcific task at given time.");
t.cancel();
}
}, 10000);