Java – How do I defer a method in a for loop in Java?

How do I defer a method in a for loop in Java?… here is a solution to the problem.

How do I defer a method in a for loop in Java?

I’m having trouble delaying methods assign_backgrounds() in a for loop. I’m trying to create a Simon says game, but instead of delaying and showing the next button “Simon” presses, I show all the buttons at once. Any help here would be appreciated. Thank you.

boolean simonsTurn = true;
int x = 4;
int s;
int delay = 1000;
int array_values[] = new int[]{1,2,3,4};


public void simonSays() {
    // running = true;
    if (simonsTurn == true) {
        go();

        for (int i = 0; i < x; i++) {
            Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                public void run() {
                    go();
                }
            }, 1000);
        }            
    }
}

public void go(){
    s = random_int_between(0,3);
        assign_backgrounds(array_values[s]);
}

public void assign_backgrounds( int array_values ){

    Handler handler = new Handler();

    if( array_values == 1){
        button1_.invalidate();
        button1_.setBackgroundResource(R.drawable.goatclicked);
        button1_.refreshDrawableState();

        handler.postDelayed(new Runnable(){
        public void run(){
        button1_.invalidate();
        button1_.setBackgroundResource(R.drawable.goat);
        button1_.refreshDrawableState();}}, 1000);
        }
    else if( array_values == 2){
        button2_.invalidate();
        button2_.setBackgroundResource(R.drawable.pigclicked);
        button2_.refreshDrawableState();

        handler.postDelayed(new Runnable(){
            public void run(){
                button2_.invalidate();
                button2_.setBackgroundResource(R.drawable.pig);
                button2_.refreshDrawableState();}}, 1000);
    }
    else if( array_values == 3){
        button3_.invalidate();
        button3_.setBackgroundResource(R.drawable.chickenclicked);
        button3_.refreshDrawableState();

        handler.postDelayed(new Runnable() {
            public void run() {
                button3_.invalidate();
                button3_.setBackgroundResource(R.drawable.chicken);
                button3_.refreshDrawableState();}}, 1000);
    }
    if( array_values == 4) {
        button4_.invalidate();
        button4_.setBackgroundResource(R.drawable.cowclicked);
        button4_.refreshDrawableState();

        handler.postDelayed(new Runnable(){
            public void run(){
                button4_.invalidate();
                button4_.setBackgroundResource(R.drawable.cow);
                button4_.refreshDrawableState();}}, 1000);
    }
}

Solution

This is because you are creating handlers very quickly, and then they all start at the same time. You should study how the handler works and asynchronous/background tasks.

Now back to your question, you’re calling a loop, it’s creating handlers consecutively, and they’re creating very fast (nanoseconds). As a result of your postDelayed() call, they will all start 1 second from that creation time. That’s why everything pops up at the same time! All of these deferred posts are executed on concurrent background threads almost simultaneously.

You want global int i instead of for(int i,...) looping, just add it to the top of the file.

At the end of any turn of Simon, in the assign_background statement in if, else if (at the end of Runnables, then you’re going to call go().

This can cause problems because you are trying to access the main thread from all these background threads. Therefore, when you call a function, you may have to call go the function runOnMainUIThread()quickly.

All in all, you will encounter some problems before you learn about handlers, background processes, and threads. Definitely worth learning, Android has solid documentation for reference only.

Related Problems and Solutions