Timer function adding an extra Timer on each call - java

Can anyone help me with my two Timer Functions:
The first one just makes the timer while canceling any previous one out first,
The second one just handles Cancelling the Timer
public void startInterval(int delay, int time, final String eventName){
cancelInterval();
mInterval = new Timer();
mInterval.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.i("timer", "Interval");
sendEvent(eventName, Arguments.createMap());
}
}, delay, time);
}
public void cancelInterval() {
if (mInterval != null){
mInterval.cancel();
mInterval.purge();
}
mInterval = null;
}
The problem is that the timer is multiplying every time I call it.
The first time I call, it works as intended, but after a few calls it ends up adding an extra timer per call

Related

Why for loop does not execute inside TmerTask

I want to repeat a for loop inside below code inside a service every some time ,but it print only one line and runs one time only
public void startTimer() {
timer = new Timer();
initializeTimerTask();
timer.schedule(timerTask, 10000);
}
public void initializeTimerTask() {
timerTask = new TimerTask() {
public void run() {
for (int i=0; i<10; i++){
Log.i("TAG", " inside method ");}
}
};
}
You are calling the following method.
public void schedule(TimerTask task, long delay)
So the task executes only once after delay.
If you want to execute it periodically you need to call the bellow method.(you may pass same value for delay and period)
public void schedule(TimerTask task, long delay, long period)
Your another query is it prints first line only. Most probably this is an issue with the Log. try System.out.print() instead of Log.i() to debug.
class MyTimerTask extends TimerTask {
private int counter = 1;
public void run() {
timerHandler.post(new Runnable() {
public void run() {
Toast.makeText(this, "" + counter, Toast.LENGTH_SHORT).show();
counter++;
}
});
if (counter == 10) {
myTimer.cancel();
myTimer.purge();
}
}
}
//Thats the usage like on ButtonClick
MyTimerTask myTimerTask = new MyTimerTask();
Timer myTimer = new Timer();
myTimer.schedule(myTimerTask, 500, 1000);
Do you really need to run Loop ?

Java Timer with timeout capability

I am implementing a timer:
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
//Do something;
}
},1000,1000);
But, I would like to have a timeout so that after lets say 100 tries/ 10 seconds, the timer stops automatically.
Thanks.
try
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
int n = 0;
#Override
public void run() {
System.out.println(n);
if (++n == 5) {
timer.cancel();
}
}
},1000,1000);
You can simply have a variable outside the run method that keeps count of the iteration. Make an if statement inside the run() method that cancels the timer when it hits your desired amount. Increase the variable by one everytime the run() method executes.
start another timer, as soon as above timer starts, which cancels the above timer after 10sec. check to code below as a quick solution. but better you cancel the task() instead of timer.
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
timer2.schedule(new TimerTask() {
#Override
public void run() {
timer1.cancel();
}
},0);
//Do something;
}
},1000,1000);
timer2 = new Timer();
I dont think we have java API for this in Timer class. You need to do it programmatically by implementing some custom logic based on your requirement.

Countdown clock in GWT

I want to create a countdown clock in GWT but I cannot find the right function that waits for one second. I tried with Thread.Sleep() but I think it is for another purpose.
Can you help me? This is my code.
int count=45;
RootPanel.get("countdownLabelContainer").add(countdown);
for(int i=count; i>=0; i--)
{
countdown.setText(Integer.toString(i));
// Place here the wait-for-one-second function
}
Give Timer a try (See Here).
Changing the example code real quick to something close to what you want, you'll want to buff this up for your purposes though:
public class TimerExample implements EntryPoint, ClickListener {
int count = 45;
public void onModuleLoad() {
Button b = new Button("Click to start Clock Updating");
b.addClickListener(this);
RootPanel.get().add(b);
}
public void onClick(Widget sender) {
// Create a new timer that updates the countdown every second.
Timer t = new Timer() {
public void run() {
countdown.setText(Integer.toString(count));
count--;
}
};
// Schedule the timer to run once every second, 1000 ms.
t.schedule(1000);
}
}
This sounds like something in the general area of what your looking for. Note that you can use timer.cancel() to stop the timer. You'll want to tie this in with your count (when 45 hits 0).
The following snippet showing the use of the timer works too. It shows how to schedule the timer properly and how to cancel it.
// Create a new timer that updates the countdown every second.
Timer t = new Timer() {
int count = 60; //60 seconds
public void run() {
countdown.setText("Time remaining: " + Integer.toString(count) + "s.");
count--;
if(count==0) {
countdown.setText("Time is up!");
this.cancel(); //cancel the timer -- important!
}
}
};
// Schedule the timer to run once every second, 1000 ms.
t.scheduleRepeating(1000); //scheduleRepeating(), not just schedule().

Incremental Timer

I'm currently using a Timer and TimerTask to perform some work every 30 seconds.
My problem is that after each time I do this work I want to increment the interval time of the Timer.
So for example it starts off with 30 seconds between the timer firing but I want to add 10 seconds to the interval then so that the next time the Timer takes 40 seconds before it fires.
Here is my previous code:
public void StartScanning() {
scanTask = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
wifiManager.startScan();
scanCount++;
if(SCAN_INTERVAL_TIME <= SCAN_MAX_INTERVAL){
SCAN_INTERVAL_TIME = SCAN_INTERVAL_TIME + SCAN_INCREASE_INTERVAL;
t.schedule(scanTask, 0, SCAN_INTERVAL_TIME);
}
}
});
}};
Log.d("SCAN_INTERVAL_TIME ** ", "SCAN_INTERVAL_TIME ** = " + SCAN_INTERVAL_TIME);
t.schedule(scanTask, 0, SCAN_INTERVAL_TIME);
}
REFACTORED CODE
#Override
public void StartScanning() {
t.schedule(new ScanTask(),SCAN_INTERVAL_TIME);
}
class ScanTask extends TimerTask{
#Override
public void run() {
wifiManager.startScan();
scanCount++;
if(SCAN_INTERVAL_TIME < SCAN_MAX_INTERVAL)
SCAN_INTERVAL_TIME = SCAN_INTERVAL_TIME + SCAN_INCREASE_INTERVAL;
t.schedule(new ScanTask(), SCAN_INTERVAL_TIME);
}
}
It works now but is creating a new ScanTask() every time wasteful?
Here is how I would do it:
1) Schedule the task for a single execution rather than a repeated one
2) At the end of the execution (possibly in a finally block), schedule a new single execution of the task, with a longer delay. Note that you must create a new instance of the task, otherwise the timer will complain (IllegalStateException). That means that you can't use an anonymous inner class anymore.

Pausing/stopping and starting/resuming Java TimerTask continuously?

I have one simple question regarding Java TimerTask. How do I pause/resume two TimerTask tasks based on a certain condition? For example I have two timers that run between each other. When a certain condition has been met inside the task of first timer, the first timer stops and starts the second timer, and the same thing happens when a certain condition has been met inside the task of second timer. The class below shows exactly what I mean:
public class TimerTest {
Timer timer1;
Timer timer2;
volatile boolean a = false;
public TimerTest() {
timer1 = new Timer();
timer2 = new Timer();
}
public void runStart() {
timer1.scheduleAtFixedRate(new Task1(), 0, 1000);
}
class Task1 extends TimerTask {
public void run() {
System.out.println("Checking a");
a = SomeClass.getSomeStaticValue();
if (a) {
// Pause/stop timer1, start/resume timer2 for 5 seconds
timer2.schedule(new Task2(), 5000);
}
}
}
class Task2 extends TimerTask{
public void run() {
System.out.println("Checking a");
a = SomeClass.getSomeStaticValue();
if (!a) {
// Pause/stop timer2, back to timer1
timer1.scheduleAtFixedRate(new Task1(), 0, 1000);
}
// Do something...
}
}
public static void main(String args[]) {
TimerTest tt = new TimerTest();
tt.runStart();
}
}
So my question is, how do I pause timer1 while running timer2 and vice versa while timer2 is running? Performance and timing is my main concern as this needs to be implemented inside another running thread. By the way I am trying to implement these concurrent timers on Android.
Thanks for your help!
From TimerTask.cancel():
Note that calling this method from
within the run method of a repeating
timer task absolutely guarantees that
the timer task will not run again.
So once cancelled, it won't ever run again. You'd be better off instead using the more modern ScheduledExecutorService (from Java 5+).
Edit: The basic construct is:
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
exec.scheduleAtFixedRate(runnable, 0, 1000, TimeUnit.MILLISECONDS);
but looking into it there's no way of cancelling that task once its started without shutting down the service, which is a bit odd.
TimerTask might be easier in this case but you'll need to create a new instance when you start one up. It can't be reused.
Alternatively you could encapsulate each task as a separate transient service:
final ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
Runnable task1 = new Runnable() {
public void run() {
a++;
if (a == 3) {
exec.shutdown();
exec = Executors.newSingleThreadScheduledExecutor();
exec.scheduleAtFixedRate(task2, 0, 1000, TimeUnit.MILLISECONDS)
}
}
};
exec.scheduleAtFixedRate(task1, 0, 1000, TimeUnit.MILLISECONDS);
easiest solution i found: just add a boolean in the run code in the timer task, like so:
timer.schedule( new TimerTask() {
public void run() {
if(!paused){
//do your thing
}
}
}, 0, 1000 );
If you have already canceled one timer, you can't re-start it, you'll have to create a new one.
See this answer, it contains a video and the source code how I did something similar.
Basically there are two method: pause and resume
In pause:
public void pause() {
this.timer.cancel();
}
In resume:
public void resume() {
this.timer = new Timer();
this.timer.schedule( aTask, 0, 1000 );
}
That makes the perception of pause/resume.
If your timers perform different actions based on the state of the application you may consider use the StatePattern
Fist define a abstract state:
abstract class TaskState {
public void run();
public TaskState next();
}
And provide as many states as you like. The key is that one state leads you to another.
class InitialState extends TaskState {
public void run() {
System.out.println( "starting...");
}
public TaskState next() {
return new FinalState();
}
}
class FinalState extends TaskState {
public void run() {
System.out.println("Finishing...");
}
public TaskState next(){
return new InitialState();
}
}
And then you change the state in your timer.
Timer timer = new Timer();
TaskState state = new InitialState();
timer.schedule( new TimerTask() {
public void run() {
this.state.run();
if( shouldChangeState() ) {
this.state = this.state.next();
}
}
}, 0, 1000 );
Finally, if what you need is to perform the same thing, but at different rates, you may consider using the TimingFramework. It is a bit more complex but let's you do cool animations, by allowing the painting of certain component take place at different rates ( instead of being linear )
In my opinion, this is somewhat misguided. If your code needs time guarantees, you can't use Timer anyway, nor would you want to. "This class does not offer real-time guarantees: it schedules tasks using the Object.wait(long) method."
The answer, IMHO, is that you don't want to pause and restart your timers. You just want to suppress their run methods from doing their business. And that's easy: you just wrap them in an if statement. The switch is on, they run, the switch is off, they miss that cycle.
Edit: The question has shifted substantially from what it was originally, but I'll leave this answer in case it helps anyone. My point is: if you don't care when your event fires in the N millisecond span (just that it doesn't EXCEED once every N milliseconds), you can just use conditionals on the run methods. This is, in fact, a very common case, especially when N is less than 1 second.
Reviewing your source code, here are the changes ( which pretty much validate my previous answer )
In task1:
// Stop timer1 and start timer2
timer1.cancel();
timer2 = new Timer(); // <-- just insert this line
timer2.scheduleAtFixedRate(new Task2(), 0, 1000);
and in task2:
// Stop timer2 and start timer1
timer2.cancel();
timer1 = new Timer(); // <-- just insert this other
timer1.scheduleAtFixedRate(new Task1(), 0, 1000);
It runs on my machine:
Android won't reuse a TimerTask that has already been scheduled once. So it's necessary to reinstantiate both the Timer and TimerTask, for example like this in a Fragment:
private Timer timer;
private TimerTask timerTask;
public void onResume ()
{
super.onResume();
timer = new Timer();
timerTask = new MyTimerTask();
timer.schedule(timerTask, 0, 1000);
}
public void onPause ()
{
super.onPause();
timer.cancel(); // Renders Timer unusable for further schedule() calls.
}
I am able to stop a timer and a task using following code:
if(null != timer)
{
timer.cancel();
Log.i(LOG_TAG,"Number of cancelled tasks purged: " + timer.purge());
timer = null;
}
if(task != null)
{
Log.i(LOG_TAG,"Tracking cancellation status: " + task.cancel());
task = null;
}
Timer timer1;
private boolean videoCompleteCDR=false;
private boolean isVideoPlaying=false;
int videoTime=0;
private int DEFAULT_VIDEO_PLAY_TIME = 30;
#Override
public View onCreate(){
isVideoPlaying = true; //when server response is successfully
}
#Override
public void onPause() {
super.onPause();
if(isVideoPlaying ) {
if(this.timer1 !=null) {
this.timer1.cancel();
}
}
}
#Override
public void onResume() {
super.onResume();
if(isVideoPlaying && !videoCompleteCDR) {
callTimerTask();
}
}
#Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (!hidden) {
printLog( "GameFragment visible ");
if(isVideoPlaying && !videoCompleteCDR) {
callTimerTask();
}
} else {
printLog("GameFragment in visible ");
if(isVideoPlaying) {
if(this.timer1 !=null) {
this.timer1.cancel();
}
}
}
}
private void callTimerTask() {
// TODO Timer for auto sliding
printLog( "callTimerTask Start" );
timer1 = new Timer();
timer1.schedule(new TimerTask() {
#Override
public void run() {
if (getActivity() != null) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
if (getActivity() == null) {
return;
}
videoTime++;
if(DEFAULT_VIDEO_PLAY_TIME ==videoTime){
videoCompleteCDR=true;
Log.e("KeshavTimer", "callTimerTask videoCompleteCDR called.... " +videoTime);
destroyTimer();
}
Log.e("KeshavTimer", "callTimerTask videoTime " +videoTime);
}
});
} else {
printLog("callTimerTask getActivity is null ");
}
}
}, 1000, 1000);
// TODO 300, 2000;
}
private void destroyTimer(){
this.timer1.cancel();
}

Categories