italianfranny
italianfranny

Reputation: 13

How to schedule a random timing (every random minutes) event

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

Answers (2)

user12875475
user12875475

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

Nyamiou The Galeanthrope
Nyamiou The Galeanthrope

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

Related Questions