I'm working on an android Tetris game. And an IllegalStateException occurred when executing
timer.scheduleAtFixedRate (task, 0L, milliseconds);
in
public void setTimerInterval (int milliseconds) {
timer.cancel ();
timer = new Timer ();
timer.scheduleAtFixedRate (task, 0L, milliseconds);
}
Am I doing this wrongly or something?
I need to cancel the timer and create a new one because I cannot change the interval of the timer unless you schedule a new task for it, right?
I read a post here and here is a quote of one of the answers:
A timer can only be scheduled once. If IllegalStateException isn't happening when you call cancel(), but when you try to reschedule the timer, just reinstantiate the timer and then schedule it. Otherwise, I'm not sure.
I didn't use the accepted answer of the that question because it's about pausing and resuming the timer.
I reinstantiated the timer as shown above but there is still a IllegalStateException.
Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
// do the task here
handler.postDelayed(this, milliseconds); // set time here to refresh textView
}
});
Make the milliseconds global and change that, maybe that would be a better solution.
How to change a java timer's interval
Java Timers don't have intervals. Timer tasks have intervals.
Solution: cancel and reschedule the TimerTask, not the Timer.
Related
I'm having problem with Android timer's scheduleAtFixedRate option.
Timer timer = new Timer();
TimerTask myTimerTask = new TimerTask() {
public void run() {
...
}
};
timer.scheduleAtFixedRate(myTimerTask, 0, 5000);
This snippet is doing bad things for me. It's executed in the service so every time method is called timer creates a new thread and executes the same code while the old thread is still running; that creates performance problems. I need to run the code in the run() method every 5 seconds but I want the old task to be canceled. Is there any way to handle this problem ?
You can use the timer.cancel() to stop the timer.
For example, I had an end button to finish the timer early:
finishEarlyButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
timer.cancel();
}
});
I'm writing an app that will have a list of "active alarms" for users to interact with in various ways. Each timer is represented by an object that contains a "created time" that represents when the alarm came into existence. I have a fragment that displays all of the alarms to a user, where each Alarm is represented as a RelativeLayout with a TextView containing the "age" of a timer, where age is calculated by the created time subtracted from the current time. The requirements for my application state that the age needs to be calculated and updated once every second.
Here's the code for my timer:
final Handler myHandler = new Handler();
final Runnable myRunnable = new Runnable(){
public void run()
{
alarmDuration.setText("Age: " + tempAlarm.getAge());
}
};
try {
//This timer is meant to update the time on each Alarm once a second.
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
myHandler.post(myRunnable);
}
};
//Schedule the timer to go every second.
timer.schedule(timerTask, 0, 1000);
}
catch(Exception e)
{
e.printStackTrace();
}
Each alarm view has its own Handler, Runnable, and Timer. Here's where my problem lies: When I am displaying less than 10 of these timers, the app seems to run fine and can manage the updating with no problem. However, I tried loading somewhere in the realm of 100 alarms, and the application began to drop frames (as seen in my console). On configuration change (such as rotating the screen), I was getting dropped frames in the realm of 50-60.
Is this a good way to update these textViews or is there a method that would create less of a drag on the application? One idea I had was to possible put the IDs of all the alarm age views into an ArrayList and then have just one Handler, Runnable, and Timer to update the entire list.
Any other suggestions would be greatly appreciated!
Here is the code snippet:
Timer t = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
//change the timer rate of scheduleAtFixedRate here
}
};
//every 10 sec
t.scheduleAtFixedRate(task, new Date(), 10000);
Could anyone tell me how to change the rate of timer to t.scheduleAtFixedRate(task, new Date(), 30000) in method run from TimerTask instance?
Thanks a lot!
You can't modify an existing schedule, but you can cancel() the TimerTask that's executing, and reschedule it for the new period.
There is no option to reschedule the timer that is already running. You need to cancel the current task and reschedule it with your new interval.
Pausing/stopping and starting/resuming Java TimerTask continuously?
I need tu update my TextView every second. I wrote it with Timer and TimeTask but everyone says its deprecated method.
Can someone show me how to make simple timer which updates TextView every 1 second with possibility stop it from UI?
You can use a handler or a count down timer
Handler m_handler;
Runnable m_handlerTask ;
m_handler = new Handler();
m_handlerTask = new Runnable()
{
#Override
public void run() {
// do something. update text view.
m_handler.postDelayed(m_handlerTask, 1000);
}
};
m_handlerTask.run();
To stop
m_handler.removeCallbacks(m_handlerTask);
Check this link for countdowntimer ,handler, timer
Android Thread for a timer
No need to create a separate Handler for this (as in the currently accepted answer). In stead, just postDelayed() the Runnable directly to the TextView's internal message queue:
Runnable runnable = new Runnable () {
#Override public void run() {
// do some work, then repost:
textview.postDelayed(runnable, 1000);
}
};
// post with an initial 1000 ms delay
textview.postDelayed(runnable, 1000);
// or post without an initial delay
textview.post(runnable);
// or even run the runnable right away the first time
runnable.run();
Alternatively, if all you're trying to accomplish is to 'redraw' the TextView, use invalidate() (or postInvalidate() from a non-UI thread). There are also overloads that allow you to restrict the invalidation to a specific rectangle, which you can potentially exploit for a more efficient implementation.
You could use a simple handler to do what you need to do. Anyway, with the scheduler way you could do:
private ScheduledExecutorService scheduler;
...
if(scheduler != null)
{
scheduler.shutdown();
scheduler = null;
}
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new Runnable()
{
public void run()
{
// do your stuff...
}
}, Consts.KEEP_ALIVE_TIMEOUT, Consts.KEEP_ALIVE_TIMEOUT, TimeUnit.MINUTES);
i wan't a timer do a job every 2.5 seconds (at the start of the program),
that is working with the following code.
Timer timer = new Timer();
timer.schedule(new TimerTask() {
// #Override
#Override
public void run() {
here is the code, and i do Speed = Speed-500
}, Speed,Speed);
Speed is a int:
public int Speed=2500;
buth the problem is that the speed of the timer stays on the 2500, while the variable speed lowers each time with 500, so that part is working. Only the timer doesn't check if Speed has changed.
Can somebody help me with this?
you cant do that because it will fix that with Timer once you done the schedule.
Schedules the specified task for repeated fixed-delay execution, beginning after the specified delay. Subsequent executions take place at approximately regular intervals separated by the specified period.
In this case you can cancel the previous one and schedule new TimerTask.
Timer timer = new Timer();
initialize the speed here
loop based on time
timer.schedule(new TimerTask() {
// #Override
#Override
public void run() {
here is the code, and i do Speed = Speed-500
}, Speed,Speed);