0

I have a code to be executed every x milliseconds, where x is changeable during the app life cycle.

Right now I use the postDelayed function of an handler, but I am not able to manage the situation when the delay changes.

handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        // do some staff

        handler.postDelayed(this, x);
    }
}, x);   

My problem is that in other parts of the app the x value can change, and I need to execute the code in the run function instantly after the change, and continue with the infinite execution of the delayed code (with new value of x).

Giacomo M
  • 4,450
  • 7
  • 28
  • 57

2 Answers2

2

Save a reference to your Runnable and keep the delay as class variable like this:

private Long x = 1000L;
private Runnable r = new Runnable() {
    @Override
    public void run() {
        // do some staff
        handler.postDelayed(this, x);
    }
}

then

handler.post(r);

to kick it off.

Then create a setter and getter for x that takes care of the change:

setX(Long: value){ 
    if(x != value){
        x = value
        handler.removeCallbacks(r);
        //run immediately
        handler.post(r);
    }
}

getX(){ return x };
leonardkraemer
  • 6,573
  • 1
  • 31
  • 54
  • Can you be pls more explanatory? I do not understand what I have to change in my code. – Giacomo M Dec 04 '18 at 16:51
  • see the edit. The trick is to use [getters and setters](https://stackoverflow.com/questions/2036970/how-do-getters-and-setters-work) – leonardkraemer Dec 04 '18 at 16:56
  • Thanks. This code is in service, what about get and set in a service? How can I solve this? – Giacomo M Dec 04 '18 at 17:02
  • How do you change `x`? Make sure `x` is in the service class, then it works. – leonardkraemer Dec 04 '18 at 17:08
  • also see https://stackoverflow.com/questions/8341667/bind-unbind-service-example-android on how to communicate with your service. – leonardkraemer Dec 04 '18 at 17:09
  • I change x in SharedPreferences. Right now I run the code every smallest x value possible, and in the "run" function I check the value and if the code is to be executed. – Giacomo M Dec 04 '18 at 17:10
  • That does not work, because shared preferences do broadcast the change. See my previous comment on how to communicate with the service properly. – leonardkraemer Dec 04 '18 at 17:11
  • 1
    You really oversimplified your problem in the question by not mentioning that the code runs in a service and that x is in shared preferences. The question as it was asked is solved, please stop adding new problems, rather think about the answers you got and how to use them and come back with a new question if you face further problems. – leonardkraemer Dec 04 '18 at 17:15
0

how about make new class that has x as static variable

class DelayInterval { 
    public static int x = 1000;
}

and when call your postDelay

handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        // do some staff

        handler.postDelayed(this, DelayInterval.x);
    }
}, DelayInterval.x);   

and somewhere in you code , you can change x

DelayInterval.x = 3000;
Ali Faris
  • 17,754
  • 10
  • 45
  • 70
  • The problem is that if I have a 100 secs "x", and I change it in 1 sec, there is a chance that the next run will be after 99 secs, instead I need to be executed instantly when the x value changes. – Giacomo M Dec 04 '18 at 17:04
  • then you need to cancel the process when change `x` and call it again with new value of x , checkout this link https://stackoverflow.com/questions/4378533/cancelling-a-handler-postdelayed-process – Ali Faris Dec 04 '18 at 17:09