Is there any possibility to pause&resume a TimerTask in Android? - java

I'm calling this tasks:
TimerTask taskA = new ThreadA(this);
TimerTask taskB = new ThreadB(this);
tasks.add(taskA);
tasks.add(taskB);
timer.schedule(taskA, 10000);
timer.schedule(taskB, 5000);
And here are the two TimerTasks:
public class ThreadA extends TimerTask {
private Ghost ghost;
public GhostThread(Ghost ghost) {
this.ghost = ghost;
}
#Override
public void run() {
ghost.stopBeingDeadAndBeAwesomeAgain();
}
}
public class ThreadB extends TimerTask {
private Ghost ghost;
public WarnThread(Ghost ghost) {
this.ghost = ghost;
}
#Override
public void run() {
ghost.beDeadAgain();
}
}
As you can see, I just call a method after 5 resp. 10 seconds. From time to time I would like to pause the "countdown". This means i want that the time until the 5 seconds are passed isn't running anymore. And then in a later point in time, I would like to resume it.
How can I achieve that??

The simplest solution would be to simply make a copy of the TimerTask, cancel it to pause, purge if you want, and then reschedule it to resume.
// pause
long timeLeft = 5000 - (new Date().getTime() - taskB.scheduledExecutionTime());
ThreadB taskBpaused = taskB.clone();
taskB.cancel();
timer.purge();
taskB = taskBpaused;
// resume
timer.schedule(taskB, timeLeft, ...);
Important note: if the task hasn't run yet, then this won't work. Google's documentation states that if it hasn't run, scheduledExecutionTime() will return an undefined value, and I don't have the capability to test what exactly that means at the moment. Needless to say, if you aren't sure it's already run, you'll need some kind of conditional to make sure the value isn't undefined.

Related

Multiple Timers which can be monitored and adjusted

I need a way to have a timer that is running on start command. Initially, the timer will be told how long to run for. However, i need a way to change this mid-way in between. If a user specifies that they would like to change the time the timer runs (by either decreasing, increasing or even ending the timer all together). I also want to be able to update the UI by showing the current time in minutes:seconds format.
The user may also want to spawn multiple timers - so they should have a way of monitoring and accessing different timers which they have set..
Currently this is what i have - from what i can tell, it works.. but i don't feel too good about it :S how can i make this better? Or what is the right way of doing this? Keep in mind that there will be other things happening while this timer is running - for instance, the user may be interacting with the UI and executing different commands un-related to the timer..
I really don't know much about threads or threading... so this is relatively new to me..
thanks in advance!
In Main:
//every time they request for a new timer, i will instantiate a new Task object..
Task task = new Task();
task.run()
task.getTaskTime();
Task.java:
public class Task extends Thread{
#Override
public void run()
{
timer = new Timer(60 * 60);
timer.start();
}
public boolean getTImerRunning() {
return timer.timerRunning;
}
public double getTaskTime() {
return timer.currentTime;
}
}
In Timer.java:
public class Timer extends Thread {
public static final int DEFAULT_TIMER = 180;
private long startMinute = 0;
private int _timer;
public double currentTime = 0;
public boolean timerRunning = true;
Timer(int timer) {
this._timer = timer;
}
Timer() {
this._timer = DEFAULT_TIMER;
}
#Override
public void run(){
long start = System.currentTimeMillis();
startMinute = start;
while(elapsedTime() <= this._timer) {
currentTime = elapsedTime();
}
timerRunning = false;
}
/**
* Return elapsed time since this object was created.
*/
private double elapsedTime() {
long now = System.currentTimeMillis();
return (now - startMinute);
}
}
Every time the user creates a "timer", do not create a new Task, but create an object MyTimer that holds the creation time and countdown duration and add the instance to an ArrayList.
The very first and only the first time, a user creates a timer you will create a task that executes every second. When that task executes it updates the UI and cycles through the ArrayList and updates each instance of MyTimer by adjusting the countdown duration.
That should keep things simple and reduce overhead.
Good Luck!

Troubles with Timer - android

i have a problem with a method that i want to be called every x seconds.
In the constructor of my class I have something like that :
public class MyClass extends RelativeLayout{
public MyClass(Context context) {
// bla bla….
mTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
callMyMethodPeriodically();
}
}, 0, 20000); // every 20 seconds..
}
}
When I press the back button, the callMyMethodPeriodically method still is being called..
Even if i exit the application!
Do you have any ideas?? How can i stop this periodically calling?
Thank you
Try to override the onPause method on your Activity, the onPause will be called when the system is about to start resuming a previous activity. This is typically used to commit unsaved changes to persistent data, stop animations and other things that may be consuming CPU, etc. Implementations of this method must be very quick because the next activity will not be resumed until this method returns.
#Override
protected void onPause() {
super.onPause();
mTimer.cancel();
mTimer.purge();
mTimer = null;
}
You can try timer.canel() method or you can do it by this way
private Runnable runnable = new Runnable()
{
public void run()
{
//
// Do the stuff
//
handler.postDelayed(this, 1000);
}
};
and to stop:
handler.removeCallbacks(runnable);
or this way
you could look into using a ScheduledThreadPoolExecutor instead of a Timer.
Usage is pretty straight forward. You create an instance of an executor:
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor( 1 );
And then when you want to add a task you call:
executor.scheduleAtFixedRate( myRunnable, delay, interval, unit );
Where myRunnable is your task (which implements the Runnable-interface), delay is how long before the task should be executed the first time, interval is time between the execution of the task after first execution. delay and interval are meassured based on the unit parameter, which can be TimeUnit.* (where * is SECONDS, MINUTES, MILLISECONDS etc.).
Then to stop the execution you call:
executor.shutdownNow();

My java class Updater don't update

I would like to know where is the problem in this class, I'm making a class that every n seconds make something, but it appear to do it only 1 time.
this is the class
import java.util.Timer;
import java.util.TimerTask;
public class Updater {
private Timer timer;
public Updater(int seconds){
timer = new Timer();
timer.schedule(new UpdaterTask(), seconds*1000);
}
class UpdaterTask extends TimerTask {
public void run() {
System.out.println(Math.random());
timer.cancel();
}
}
}
and this is the test
public class TestUpdater {
public static void main(String[] args){
new Updater(1);
}
}
i think that this test have to give me a random number every second but after the first second the process terminate.
Sorry for the bad english and thanks for any suggestion
schedule(task, delay) only execute the task once. schedule(task, delay, period) execute the task repeatedly with fixed delay.
timer.schedule(new UpdaterTask(), 0, seconds * 1000)
Remove cancel()
// timer.cancel();
You need to comment out, the timer.cancel() call. This is making the timer itself stop after the first execution of its timer task.
Then for repeated execution, you should call scheduleAtFixedRate method, with delay == 0, to start the task immediately, and period == x seconds, to run it every x seconds.
class Updater {
private Timer timer;
public Updater(int seconds){
timer = new Timer();
timer.scheduleAtFixedRate(new UpdaterTask(), 0, seconds*1000); // use scheduleAtFixedRate method
}
class UpdaterTask extends TimerTask {
public void run() {
System.out.println(Math.random());
//timer.cancel(); --> comment this line
}
}
}
When your main() thread terminates the application also terminates.
Just add Thread.sleep(10000) at the end of your code. It will then work for 10 seconds.
AND
Consult this answer for how to use the cancel method. I think you did not want to use it there.
AND
Change the scheduling type, use
timer.scheduleAtFixedRate(new UpdaterTask(), 0, seconds*1000);

Calling run() method of TimerTask

For the problem I am solving, I have to run a series of calls at periodic intervals. To achieve this, I have implemented TimerTask. However, I also want to notify the timertask sometimes and need to call the same methods when certain conditions are met even if the timer did not expire. My code looks similar to this.
//File TimerTaskA.java
public class TimerTaskA extends TimerTask
{
#Override
public void run()
{
processEvent1();
processEvent2();
processEvent3();
}
}
//File ProcessEventManager.java
public class ProcessEventManager
{
public TimerTaskA timerTask;
public ProcessEventManager()
{
initTimerTask();
}
public void initTimerTask()
{
Timer timer = new Timer("TimerTaskA", true);
timerTask == new TimerTaskA();
timer.schedule(timerTask , 0, 10000);
}
public void conditionalTask()
{
long time = System.currentTimeMillis();
// some condition statement. here it happens to be time in millisecs ends with 2 or 3.
if (time%10 == 2 || time%10 == 3)
timerTask.run();
}
}
In the ProcessEventManager.conditionalTask() method is it correct to call TimerTask's run() method directly to get through this situation? Is there a better way design wise to solve something like this?
The processEvent methods might be time consuming methods, and I do not want the thread running ProcessEventManager to be blocked while executing those methods. For the TimerTask to take care of running those methods in both the cases when timer expires as well as the condition in ProcessEventManager.conditionalTask is satisfied, what is the best way to do it?
Basically, yes, it is possible to do as you wrote, but a clearer way will be to call some processing method from inside the TimerTask, and when you want to perform this operation, call it directly, not through the TimerTask object.
public class TimerTaskA extends TimerTask
{
public void doCoolThings()
{
processEvent1();
processEvent2();
processEvent3();
}
#Override
public void run()
{
doCoolThings();
}
}
in the other class, when needed:
timerTask.doCoolThings();
The reason as I see it, is mainly because the purpose of run is to serve as the thread (or caller) entry point, not to do a specific task.

Android - run a function every X milliseconds while condition true?

I just want to run a function myFunction() every X milliseconds while an external flag is true. However I've had no luck with Threads (app crashes), Timers (app crashes). Handlers/runnables are a bit better but typically I'll have something like:
Runnable rr = new Runnable() {
public void run() {
if (flag1 == true) {
myFunction();
} else {
return;
}
}
};
handler.postDelayed(rr, 1000);
But then the problem is execution will come one after another after 1000 milliseconds. I want one execution of myFunction to happen, wait 1000ms, call myFunction, wait 1000ms, call myFunction, etc, until flag1 becomes false.
I've been stuck on this for a while, so any help is much appreciated.
EDIT - more question info
The handler is defined as follows:
private Handler handler = new Handler();
And its class is a BroadcastReceiver where I'm trying to listen for flag changes based on asynchronous events from external hardware.
This will loop and check the flag every second for the lifetime of the application.
Thread myThread = new Thread(new UpdateThread());`
myThread.start();`
public class UpdateThread implements Runnable {
#Override
public void run() {
while(true)
{
if (flag1 == true)
myFunction();
myThread.sleep(1000);
}
}
also you may want to look at a service
http://developer.android.com/reference/android/app/Service.html

Categories