John Kheng
John Kheng

Reputation: 49

How to set a delayed in Android

I'm aware or the Thread.sleep() and postDelayed() function in java/androidStudio. But here is the issue, I'm creating a replicate of Simon says game.

I created a generateSequence() function that puts number of 1-9 randomly into an array called sequence. After that, I need to display these sequence, which basically changes the background of a textView for a second and then back to its original background using the postDelayed() function.

Here is my code:

private void displaySequence(){
    for(int i = 0; i < sequence.size(); i++) {
        if(sequence.get(i) == 1) {
            viewCard11.setBackgroundResource(R.drawable.text_view_circle4);
            proceed = false;
            handler.postDelayed(() -> {
                viewCard11.setBackgroundResource(R.drawable.text_view_circle3);
                proceed = true;
            }, 1000);
        } 
        else if(sequence.get(i) == 2) {} 
        else if(sequence.get(i) == 3) {} 
        else if(sequence.get(i) == 4) {} 
        else if(sequence.get(i) == 5) {} 
        else if(sequence.get(i) == 6) {} 
        else if(sequence.get(i) == 7) {} 
        else if(sequence.get(i) == 8) {} 
        else if(sequence.get(i) == 9) {}
        while(!proceed) {}
    }
}

But the problem with postDelayed() is that only whatever is inside the function is delayed. Meaning if this sequence had 2 element, it will simultaneously blink the background. The for loop doesn't wait for the postDelayed to finish whatever it is suppose to do, but instead it increments and proceed to put the next postDelayed.

To solve this issue, I tried to use a proceed boolean variable as a delay. What I do is that, before we call the postDelayed, I set proceed as false. Since it will not wait for postDelayed(), it will go to the next line of code which is the while loop.

By setting the proceed as false, I use it to create a infinite loop. But this infinite loop will be broken by the completed postDelayed() as proceed will be set to true in it, then the code can continues the for loop.

But I not sure why it simply doesn't work. When I run the code, it just displayed a blank screen. It seemed like the problem resides within the infitine while loop and postDelayed() can't update the proceed variable.

I tried using Thread.sleep(1000) as a replacement of postDelayed, but during startup, the program simply shows a white background for however long the parameter is passed to Thread.sleep()

I have exhausted my option and I hope someone has a better idea. Thank you.

Upvotes: 1

Views: 1305

Answers (1)

Stefan Olteanu
Stefan Olteanu

Reputation: 52

The loop does not wait for the postDelayed because what's inside the postDelayed happens async. This means that it works independently from the UI thread, on a second thread. What you want to accomplish is to make the UIthread wait for a period of time, and not start another thread after a specific period. You could try to use the handler in this way:

Handler handler=new Handler()
{

public void handleMessage(Message msg)
{
   if(msg.what==0)
{
 viewCard11.setBackgroundResource(R.drawable.text_view_circle3);
      proceed = true;
}

}
};

and then you may use the handler like this:

handler.postDelayed(() -> 
{            
 //does nothing just waits 1 second and then send empty message
 handler.sendEmptyMessage(0)
}, 1000);

Upvotes: 1

Related Questions