Search code examples
javaandroidrunnable

Modify external variable of runnable executed periodically on Java


I am trying to execute on Android every five seconds a Runnable that should insert these values on the database:

value | seconds delayed
  1            0
  2            5
  3            10
  4            15
  3            20
  2            25
  1            30

My approach was the following:

public class MainActivity extends AppCompatActivity{
    public static int currentValue;
    public static int directionSign;

    protected void onCreate(Bundle savedInstanceState) {
        generateData();
    }

    public void generateData(){

        currentValue = 1;
        int directionSign = 1;

        while(!(directionSign == -1 && currentValue == 0)){

            Handler handler=new Handler();
            Runnable r=new Runnable() {
                public void run() {
                    long currentTimestamp = System.currentTimeMillis();
                    db.insertValue(currentTimestamp, currentValue);
                }
            };

            //Insert two registers for each state
            for(int i=0; i<2; i++) {
                handler.postDelayed(r, 5000);
            }

            if(currentValue == 4){
                directionSign = -1;
            }

            currentValue+= directionSign;


        }

        handler.postDelayed(r, Constants.MEASUREMENT_FREQUENCY);

    }
}

This code however, gets stucked on value 1. My question is, how can I do it so it generated the output showed on the table?


Solution

  • Since your while loop iterates 7 times and you spawn 14 threads, all the threads will execute after 5 seconds at once not EVERY 5 seconds. So for your use case you can create only one thread that writes in the database every 5 seconds:

    new Thread(new Runnable() {
                public void run() {
                    int currentValue = 1;
                    int directionSign = 1;
                    while(!(directionSign == -1 && currentValue == 0)) {
                        long currentTimestamp = System.currentTimeMillis();
                        db.insertValue(currentTimestamp, currentValue);
                        if(currentValue == 4){
                            directionSign = -1;
                        }
                        currentValue+= directionSign;
                        try {
                            Thread.sleep(5000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();;