Reputation: 13
I'm developing an Android App, I'm trying to manage a Vibration event. I need to schedule it every random minutes when a switch is checked. I have been using this code:
int delay3 = (60 + new Random().nextInt(60)) * 1000;
timer3.schedule(timerTask3, 0, delay3);
but the timer doesn't change delay3
until the switch is unchecked and checked again. Is there a way to schedule the event at random timing i.e. delay3
should change every time the task is running without unchecking the switch?
Thank you.
Upvotes: 1
Views: 2435
Reputation: 1
You can also use the postDelayed
method of the android.os.Handler
class instead of
scheduleAtFixedRate
method of the java.util.Timer
class.
Simply create an instance of android.os.Handler
class and invoke the postDelayed
method of the android.os.Handler
instance instead of creating an instance of java.util.Timer
class and invoke the scheduleAtFixedRate
method of the java.util.Timer
instance.
Note that you have to replace TimerTask
interface by Runnable
interface.
At the end of the run
method of the Runnable
instance (passed as first parameter to the postDelayed
method of the android.os.Handler
instance) invoke again with new random delay the postDelayed
method of the same android.os.Handler
instance with the same Runnable
instance!
No need to create new instance of TimerTask
and no need to create new instance of Runnable
!
This is more efficient because less objects are allocated on the heap memory and thus the garbage collector is less busy at deallocating objects from the heap memory this way!
There is a demo I wrote myself using my idea:
import android.os.Handler;
import java.util.Random;
public class Demo
{
private boolean postAgain;
public void start()
{
postAgain = true;
final Handler handler = new Handler();
final Random random = new Random();
final Runnable runnable = () ->
{
log.d("Hello");
if (postAgain)
{
handler.postDelayed(runnable,random.nextInt(10000));
}
};
handler.postDelayed(runnable,random.nextInt(10000));
}
public void stop() { postAgain = false; }
Note that the above code makes use of Java 8 lambda expression.
In Java 7 and below you can create an instance of Runnable
interface that implements the run
method without defining a new named class that implements
the Runnable
interface.
Also note that all the locals of the start
method must be all final
in order to be able to use them in the lambda expression or in the run
method of the Runnable
instance.
Invoke the start
method to repeatedly print "Hello" at random delays and invoke the stop
method to stop this.
Note that the stop
method only sets a boolean
field from true to false to stop the cycle.
Upvotes: 0
Reputation: 1214
Schedule the task to run after a random delay once. Inside the task, after the desired process, reschedule it after a random delay.
Example:
Random random = new Random();
Timer timer = new Timer();
timer.schedule(new MyTimerTask(timer, random), random.nextInt(10000));
with:
private static class MyTimerTask extends TimerTask {
private final Timer timer;
private final Random random;
public MyTimerTask(Timer timer, Random random) {
this.timer = timer;
this.random = random;
}
@Override
public void run() {
System.out.println("TEST");
timer.schedule(new MyTimerTask(timer, random), random.nextInt(10000));
}
}
Upvotes: 1