friends, I have this simple timer, which is suppose to tick every 10ms for the period of 2seconds.
breathTimer = new CountDownTimer(2000, 10) {
int currStep = 0;
public void onTick(long millisUntilFinished) {
Log.e(String.valueOf(currStep*10),String.valueOf(mSecPerBreath));
currStep++;
}
public void onFinish() {
Log.e("END: "+String.valueOf(currStep*10),String.valueOf(mSecPerBreath));
}
};
breathTimer.start();
Yet it always stops too early, for example
E/END: 1640: 2000
what do you think might be the problem?
or if I set the timer to 3000, it will end in E/END: 2520: 2000
As per documentation, seems like the onTick execution time is significant compared to the countdown interval (10ms). This could be the reason for the increased period (i.e. 2520).
The calls to onTick(long) are synchronized to this object so that one call to onTick(long) won't ever occur before the previous callback is complete. This is only relevant when the implementation of onTick(long) takes an amount of time to execute that is significant compared to the countdown interval.
Related
How can I get the time left in a util.Timer?
What I want to do is to add a progressbar that displays time left until the timer starts over.
This is what I've got this far:
int seconds = 8;
java.util.Timer timer = new Timer();
timer.schedule( new TimerTask(){
public void run(){
// Do something
// Add a progressbar that displays time left until the timer "starts over".
},0,(long) (seconds*1000));
You would need a second timer to refresh the gui in a specific interval.
Another way to achieve this, would be to activate a single timer every second and update the counting in the ui. If the time is up, call your specific action.
A simple expample with console output only:
TimerTask task = new TimerTask()
{
int seconds = 8;
int i = 0;
#Override
public void run()
{
i++;
if(i % seconds == 0)
System.out.println("Timer action!");
else
System.out.println("Time left:" + (seconds - (i %seconds)) );
}
};
Timer timer = new Timer();
timer.schedule(task, 0, 1000);
It's output would be:
Time left:7
Time left:6
Time left:5
Time left:4
Time left:3
Time left:2
Time left:1
Timer action!
Time left:7
Time left:6
Time left:5
Time left:4
Time left:3
Time left:2
Time left:1
Timer action!
Time left:7
Time left:6
...
Then simply change the System.out's with your code to update the progress bar. Remember: java.util.Timer starts its own Thread. Swing is not thread safe, so you need to put every gui changing code into SwingUtilities.invokeLater()!
If you're not doing any long running tasks, every time your timer reachs the 8 seconds mark, you may want to use javax.swing.Timer directly. It uses the EDT and not its own Thread, so you don't need to synchronize your calls to Swing components with SwingUtilities.invokeLater().
Also see:
javax.swing.Timer vs java.util.Timer inside of a Swing application
All you need to do is declare a long variable timeleft in your MainActivity.
long timeleft;
Then, when you create a new Timer, set the "onTick" override to update the timeleft variable each "onTick" (which in the following example is 1000 milliseconds )
timer = new CountDownTimer(time, 1000) {
#Override
public void onTick(long millisecondsUntilFinished) {
timeleft = millisecondsUntilFinished;
}
}
Your app can access then the variable timeleft every time you need to check how much time is left.
I have a timer:
new CountDownTimer(10000, 1000) {
public void onTick(long millisUntilFinished)
{label.setText("Seconds Remaining: " + millisUntilFinished / 1000);}
public void onFinish() {doSomething();}
}.start();
It counts down from 10, and if it reaches 0 method 'doSomething()' is run. But it keeps repeating itself. I need 'doSomething()' to run only 10 times overall. Baring in mind that if the timer does not reach 0 another method needs to also run.
thanks, for any help
Yes it is good to know what doSomething() does. Moreover you may obtain the 10x execution using the onTick instead of onFinish. It really depends on what do you want to achieve. For example if doSomething is not reentrant using onTick would be not enough.
Im trying to get a timer to work in my current java project that adds 1 to an integer variable every n microseconds (e.g. 500 for 1/2 a second), within an infinite loop, so that it is always running while the program runs.
Heres the code i have currently:
public class Ticker
{
public int time = 0;
long t0, t1;
public void tick(int[] args)
{
for (int i = 2; i < 1; i++)
{
t0 = System.currentTimeMillis();
do
{
t1 = System.currentTimeMillis();
}
while (t1 - t0 < 500);
time = time + 1;
}
}
}
Everyone was so helpful with my last question, hopefully this one is just as easy
Here is an comparable ScheduledExecutorService example which will update the time variable with a 500 millisecond interval:
ScheduledExecutorService exec = Executors.newScheduledThreadPool(1);
exec.scheduleAtFixedRate(new Runnable(){
private int time = 0;
#Override
public void run(){
time++;
System.out.println("Time: " + time);
}
}, 0, 500, TimeUnit.MILLISECONDS);
This approach is preferred over using Timer.
I think you want
Thread.sleep(500);
At the moment you're consuming CPU cycles waiting for 500ms (you mention microseconds but I believe you want milliseconds). The above puts your current thread to sleep for 500ms and your process won't consume any CPU (or minimal at least - garbage collection will still be running). If you watch the CPU when you run your version you should see the difference.
See here for more info.
If you need to do it in a different thread, take a look on Timer:
int delay = 500; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
time++
}
};
new Timer(delay, taskPerformer).start();
Note that the code above cannot utilize a local variable (they must be declared as final to access them in an anonymous class). It can be a member however.
What you have is rather inefficient, since it wastes CPU cycles waiting for the next wakeup time. If I were you, I'd rewrite the function using Thread.sleep().
As to why your current code doesn't work, your for loop conditions are off, so the loop is never entered.
To have the timer code run concurrently with whatever other logic you have in your program, you'll need to look into threading.
It sounds like you might want to look into multithreading. If you search SO for this, you will find several good question/answer threads. There are also tutorials elsewhere on the web...
Have a look at Timer or better ScheduledExecutorService. They enable you to execute some action periodically and handle the computations surrounding that.
I am using a while loop with a timer.
The thing is that the timer is not used in every loop.
It is used only the first time. After the first time the statements included inside the loop are executed without the delay that i have set.
How is this even possible since the timer is included inside the while loop.
Any solutions ?
int count = 1;
while (count <= 10) {
final Handler handler = new Handler();
Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
// Stuff the while loop executes
}
});
}
}, 20000);
count++;
}
The TimerTask kicks off a new Thread and then the loop proceeds as normal.
The execution of the thread does not cause a delay to the execution of the code in your loop.
It's because you're queueing up 10 toasts all to execute in one hour. Each iteration of your loop takes only a fraction of a millisecond or maybe a tad bit more than that. To enqueue them properly, you could do 3600000 * count instead of 3600000 each time.
This is a terrible way to do it though. You should use AlarmManager for stuff like this.
You're scheduling 10 TimerTasks to execute after an hour, at the same time. So all 10 tasks are being executed after 1 hour, which makes it seem like 1 execute since all the Toast messages display at the same time. To schedule tasks at a fixed delay, with the first task starting in 1 hour, use this method:
Timer t = new Timer();
t.schedule(task, 3600000, 3600000);
This will execute until you call t.cancel().
I am using a while loop with a timer.
The thing is that the timer is not used in every loop.
It is used only the first time. After the first time the statements included inside the loop are executed without the delay that i have set.
How is this even possible since the timer is included inside the while loop.
Any solutions ?
int count = 1;
while (count <= 10) {
final Handler handler = new Handler();
Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
// Stuff the while loop executes
}
});
}
}, 20000);
count++;
}
The TimerTask kicks off a new Thread and then the loop proceeds as normal.
The execution of the thread does not cause a delay to the execution of the code in your loop.
It's because you're queueing up 10 toasts all to execute in one hour. Each iteration of your loop takes only a fraction of a millisecond or maybe a tad bit more than that. To enqueue them properly, you could do 3600000 * count instead of 3600000 each time.
This is a terrible way to do it though. You should use AlarmManager for stuff like this.
You're scheduling 10 TimerTasks to execute after an hour, at the same time. So all 10 tasks are being executed after 1 hour, which makes it seem like 1 execute since all the Toast messages display at the same time. To schedule tasks at a fixed delay, with the first task starting in 1 hour, use this method:
Timer t = new Timer();
t.schedule(task, 3600000, 3600000);
This will execute until you call t.cancel().