[java] How to set delay in android?

public void onClick(View v) {
        // TODO Auto-generated method stub
        switch(v.getId()){
        case R.id.rollDice:
            Random ranNum = new Random();
            int number = ranNum.nextInt(6) + 1;
            diceNum.setText(""+number);
            sum = sum + number;
            for(i=0;i<8;i++){
                for(j=0;j<8;j++){

                    int value =(Integer)buttons[i][j].getTag();
                    if(value==sum){
                        inew=i;
                        jnew=j;

                        buttons[inew][jnew].setBackgroundColor(Color.BLACK);
                                                //I want to insert a delay here
                        buttons[inew][jnew].setBackgroundColor(Color.WHITE);
                         break;                     
                    }
                }
            }


            break;

        }
    }

I want to set a delay between the command between changing background. I tried using a thread timer and tried using run and catch. But it isn't working. I tried this

 Thread timer = new Thread() {
            public void run(){
                try {
                                buttons[inew][jnew].setBackgroundColor(Color.BLACK);
                    sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

             }
           };
    timer.start();
   buttons[inew][jnew].setBackgroundColor(Color.WHITE);

But it is only getting changed to black.

This question is related to java android

The answer is


Using the Thread.sleep(millis) method.


You can use CountDownTimer which is much more efficient than any other solution posted. You can also produce regular notifications on intervals along the way using its onTick(long) method

Have a look at this example showing a 30seconds countdown

   new CountDownTimer(30000, 1000) {
         public void onFinish() {
             // When timer is finished 
             // Execute your code here
     }

     public void onTick(long millisUntilFinished) {
              // millisUntilFinished    The amount of time until finished.
     }
   }.start();

If you use delay frequently in your app, use this utility class

import android.os.Handler;


public class Utils {

    // Delay mechanism

    public interface DelayCallback{
        void afterDelay();
    }

    public static void delay(int secs, final DelayCallback delayCallback){
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                delayCallback.afterDelay();
            }
        }, secs * 1000); // afterDelay will be executed after (secs*1000) milliseconds.
    }
}

Usage:

// Call this method directly from java file

int secs = 2; // Delay in seconds

Utils.delay(secs, new Utils.DelayCallback() {
    @Override
    public void afterDelay() {
        // Do something after delay

    }
});

Here's an example where I change the background image from one to another with a 2 second alpha fade delay both ways - 2s fadeout of the original image into a 2s fadein into the 2nd image.

    public void fadeImageFunction(View view) {

    backgroundImage = (ImageView) findViewById(R.id.imageViewBackground);
    backgroundImage.animate().alpha(0f).setDuration(2000);

    // A new thread with a 2-second delay before changing the background image
    new Timer().schedule(
            new TimerTask(){
                @Override
                public void run(){
                    // you cannot touch the UI from another thread. This thread now calls a function on the main thread
                    changeBackgroundImage();
                }
            }, 2000);
   }

// this function runs on the main ui thread
private void changeBackgroundImage(){
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            backgroundImage = (ImageView) findViewById(R.id.imageViewBackground);
            backgroundImage.setImageResource(R.drawable.supes);
            backgroundImage.animate().alpha(1f).setDuration(2000);
        }
    });
}

You can use this:

import java.util.Timer;

and for the delay itself, add:

 new Timer().schedule(
                    new TimerTask(){
                
                        @Override
                        public void run(){
                            
                        //if you need some code to run when the delay expires
                        }
                        
                    }, delay);

where the delay variable is in milliseconds; for example set delay to 5000 for a 5-second delay.


Handler answer in Kotlin :

1 - Create a top-level function inside a file (for example a file that contains all your top-level functions) :

fun delayFunction(function: ()-> Unit, delay: Long) {
    Handler().postDelayed(function, delay)
}

2 - Then call it anywhere you needed it :

delayFunction({ myDelayedFunction() }, 300)

If you want to do something in the UI on regular time intervals very good option is to use CountDownTimer:

new CountDownTimer(30000, 1000) {

     public void onTick(long millisUntilFinished) {
         mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
     }

     public void onFinish() {
         mTextField.setText("done!");
     }
  }.start();

I think the easiest and most stable and the most useful way as of 2020 is using delay function of Coroutines instead of Runnable. Coroutines is a good concept to handle asynchronous jobs and its delay component will be this answer's focus.

WARNING: Coroutines need Kotlin language and I didn't convert the codes to Kotlin but I think everybody can understand the main concept..

Just add the Coroutines on your build.gradle:

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'

Add a job to your class (activity, fragment or something) which you will use coroutines in it:

private var job: Job = Job()
override val coroutineContext: CoroutineContext
    get() = Dispatchers.Main + job

And you can use Coroutines anywhere on the class by using launch{ } body. So you can write your code like this:

public void onClick(View v) {

    launch {

        switch(v.getId()) {
            case R . id . rollDice :
            Random ranNum = new Random();
            int number = ranNum . nextInt (6) + 1;
            diceNum.setText("" + number);
            sum = sum + number;
            for (i= 0;i < 8;i++){
                for (j= 0;j < 8;j++){
                    int value =(Integer) buttons [i][j].getTag();
                    if (value == sum) {
                        inew = i;
                        jnew = j;

                        buttons[inew][jnew].setBackgroundColor(Color.BLACK);
                        delay(2000)
                        buttons[inew][jnew].setBackgroundColor(Color.WHITE);
                        break;
                    }
                }
        }
            break;

        }
    }
}

It's All...

Dont't forget that launch{} function is asynchronous and the for loop will not wait for delay function to finish if you write like this:

launch{
    buttons[inew][jnew].setBackgroundColor(Color.BLACK);
    delay(2000)
    buttons[inew][jnew].setBackgroundColor(Color.WHITE);
}

So, launch{ } should cover the for loop if you want all the for loop to wait for delay.

Another benefit of launch{ } is that you are making the for loop asynchronous, which means it is not gonna block the main UI thread of the application on heavy processes.