How to delay a loop in android without using thread.sleep?

45,030

Solution 1

Your for loop should be:

final ImageButton[] all= {btn1, btn2, btn3, btn4};
Handler handler1 = new Handler();
for (int a = 1; a<=all.length ;a++) {
    handler1.postDelayed(new Runnable() {

         @Override
         public void run() {
              ImageButton btn5 = all[random.nextInt(all.length)];
              btn5.setBackgroundColor(Color.RED);
         }
         }, 1000 * a);
    } 
}

This way it achieves your desired behavior of staggering the color change.

Edited for syntax

Solution 2

You can use a Handler instead of for loop. You should not call Thread.sleep() on the UI thread.

final Handler handler = new Handler();
Runnable runnable = new Runnable() { 
    @Override
    public void run() {
        // do something
        handler.postDelayed(this, 1000L);  // 1 second delay
    }
};
handler.post(runnable);

Solution 3

The following code doing the task in every second:

final Handler handler = new Handler();
Runnable task = new Runnable() {
    @Override
    public void run() {
        Log.d(TAG, "Doing task");
        handler.postDelayed(this, 1000);
    }
};
handler.post(task); 

Solution 4

Try this :

public void onClick(View v) { 
    if (v == start) {   
        for (int a = 0; a<4 ;a++) {
            Handler handler1 = new Handler();
            handler1.postDelayed(new Runnable() {
                ImageButton[] all= {btn1, btn2, btn3, btn4};
                @Override
                public void run() {
                    btn5 = all[random.nextInt(all.length)];
                    btn5.setBackgroundColor(Color.RED);
                }
            }, 1000);
        } 
    }
}

Example for Delay :

final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        // Do something after 5s = 5000ms
        buttons[inew][jnew].setBackgroundColor(Color.Red);
    }
}, 5000);
Share:
45,030

Related videos on Youtube

user3153613
Author by

user3153613

Updated on July 09, 2022

Comments

  • user3153613
    user3153613 almost 2 years

    I wanted to delay a for loop without using Thread.sleep because that method make my whole application hang. I tried to use handler but it doesn't seems to work inside a loop. Can someone please point out the mistake in my code.

    public void onClick(View v) { 
        if (v == start)
        {   
            for (int a = 0; a<4 ;a++) {
    
             Handler handler1 = new Handler();
             handler1.postDelayed(new Runnable() {
    
            ImageButton[] all= {btn1, btn2, btn3, btn4};
            btn5 = all[random.nextInt(all.length)];
            btn5.setBackgroundColor(Color.RED);
    
                 @Override
                 public void run() {
    
                 }
                 }, 1000);
            } 
            }
         }
    

    Basically what I wanted to do is that I got 4 ImageButton and I change each of their background to red by using a loop in order. Thats why I need a delay inside my loop, if not all the ImageButton will just directly turn red without showing which ImageButton turn first.

    • Raghunandan
      Raghunandan over 10 years
      you don't need a for loop. you can use a Handler itself
  • Imran Ali Khan
    Imran Ali Khan over 10 years
    just call public void run() inside the loop and make parameters for your button index or button names
  • user3153613
    user3153613 over 10 years
    can you give me an example of using Handler instead of loop for my code
  • Raghunandan
    Raghunandan over 10 years
    @user3153613 use the above . that ihas 1 second delay and then instead of do something. set the background color to button
  • Raghunandan
    Raghunandan over 10 years
    it keeps on going untill you stop the handler by m_hnbdler.removeCallbacks(m_handlerTask)
  • user3153613
    user3153613 over 10 years
    It worked but I have another problem. I get an syntax error at the ImageButton btn5 = all[random.nextInt(all.length)]; when I use your code. It seems like I had to put final ImageButton[] all= {btn1, btn2, btn3, btn4}; for it to work.
  • sddamico
    sddamico over 10 years
    Edited with final added to the array.
  • Raghunandan
    Raghunandan over 10 years
    @user3153613 how do you initialize your buttons?
  • Mahdi
    Mahdi over 7 years
    this is not working because a is not specific for each runable
  • user3156040
    user3156040 over 4 years
    TextView number = findViewById(R.id.textView2); Handler handler1 = new Handler(); for (int a = 1; a<=3 ;a++) { handler1.postDelayed(new Runnable() { @Override public void run() { number.setText(String.valueOf(numbersArray[a])); } }, 1000 * a); } It says, Textview AND a needs to be decalred final! Now, how would i increase if a is final? Any ideas!
  • Abandoned Cart
    Abandoned Cart about 4 years
    This generates an error that runnable may not have been initialized, but you can replace the reference inside run with this. @Raghunandan I believe you meant handler.removeCallbacks(runnable);
  • Abandoned Cart
    Abandoned Cart about 4 years
    After looking this over a little more, I also think you want to call handler.post(runnable); rather than runnable.run(); initially.
  • Raghunandan
    Raghunandan about 4 years
    @AbandonedCart corrected it. it was a long time back thanks for correcting.
  • Abandoned Cart
    Abandoned Cart about 4 years
    @Raghunandan You copied in the optional suggestion, but did not address the error of attempting to call the variable inside its initialization. I have edited the answer to fix it.