How to call a method after a delay in Android

JavaAndroidHandlerDelay

Java Problem Overview


I want to be able to call the following method after a specified delay. In objective c there was something like:

[self performSelector:@selector(DoSomething) withObject:nil afterDelay:5];

Is there an equivalent of this method in android with java? For example I need to be able to call a method after 5 seconds.

public void DoSomething()
{
     //do something here
}

Java Solutions


Solution 1 - Java

Kotlin
Handler(Looper.getMainLooper()).postDelayed({
    //Do something after 100ms
}, 100)


Java
final Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        //Do something after 100ms
    }
}, 100);


Solution 2 - Java

I couldn't use any of the other answers in my case. I used the native java Timer instead.

new Timer().schedule(new TimerTask() {			
	@Override
	public void run() {
		// this code will be executed after 2 seconds		
	}
}, 2000);

Solution 3 - Java

Note: This answer was given when the question didn't specify Android as the context. For an answer specific to the Android UI thread look here.


It looks like the Mac OS API lets the current thread continue, and schedules the task to run asynchronously. In the Java, the equivalent function is provided by the java.util.concurrent package. I'm not sure what limitations Android might impose.

private static final ScheduledExecutorService worker = 
  Executors.newSingleThreadScheduledExecutor();

void someMethod() {
  ⋮
  Runnable task = new Runnable() {
    public void run() {
      /* Do something… */
    }
  };
  worker.schedule(task, 5, TimeUnit.SECONDS);
  ⋮
}

Solution 4 - Java

For executing something in the UI Thread after 5 seconds:

new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
    @Override
    public void run() {
        //Do something here
    }
}, 5000);

Solution 5 - Java

> #Kotlin & Java Many Ways

###1. Using Handler

Handler().postDelayed({
    TODO("Do something")
    }, 2000)

###2. Using TimerTask

Timer().schedule(object : TimerTask() {
	override fun run() {
		TODO("Do something")
	}
}, 2000)

Or even shorter

Timer().schedule(timerTask {
	TODO("Do something")
}, 2000)

Or shortest would be

Timer().schedule(2000) {
	TODO("Do something")
}

###3. Using Executors

Executors.newSingleThreadScheduledExecutor().schedule({
	TODO("Do something")
}, 2, TimeUnit.SECONDS)

> #In Java

###1. Using Handler

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        //Do something
    }
}, 2000);

###2. Using Timer

new Timer().schedule(new TimerTask() {          
    @Override
    public void run() {
        // Do something
    }
}, 2000);

###3. Using ScheduledExecutorService

private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();

Runnable runnable = new Runnable() {
  public void run() {
      // Do something
  }
  };
worker.schedule(runnable, 2, TimeUnit.SECONDS);

Solution 6 - Java

you can use Handler inside UIThread:

runOnUiThread(new Runnable() {
				
	@Override
	public void run() {
		new Handler().postDelayed(new Runnable() {
		   @Override
		   public void run() {
               //add your code here
		  }
		}, 1000);			
	}
});

Solution 7 - Java

Thanks for all the great answers, I found a solution that best suits my needs.

Handler myHandler = new DoSomething();
Message m = new Message();
m.obj = c;//passing a parameter here
myHandler.sendMessageDelayed(m, 1000);

class DoSomething extends Handler {
	@Override
    public void handleMessage(Message msg) {
      MyObject o = (MyObject) msg.obj;
      //do something here
    }
}

Solution 8 - Java

See this demo:

import java.util.Timer;
import java.util.TimerTask;

class Test {
     public static void main( String [] args ) {
          int delay = 5000;// in ms 

          Timer timer = new Timer();

          timer.schedule( new TimerTask(){
             public void run() { 
                 System.out.println("Wait, what..:");
              }
           }, delay);

           System.out.println("Would it run?");
     }
}

Solution 9 - Java

If you have to use the Handler, but you are into another thread, you can use runonuithread to run the handler in UI thread. This will save you from Exceptions thrown asking to call Looper.Prepare()

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                //Do something after 1 second
            }
        }, 1000);
    }
});

Looks quite messy, but this is one of the way.

Solution 10 - Java

I prefer to use View.postDelayed() method, simple code below:

mView.postDelayed(new Runnable() {
	@Override
	public void run() {
        // Do something after 1000 ms
	}
}, 1000);

Solution 11 - Java

Here is my shortest solution:

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        //Do something after 100ms
    }
}, 100);

Solution 12 - Java

If you are using Android Studio 3.0 and above you can use lambda expressions. The method callMyMethod() is called after 2 seconds:

new Handler().postDelayed(() -> callMyMethod(), 2000);

In case you need to cancel the delayed runnable use this:

Handler handler = new Handler();
handler.postDelayed(() -> callMyMethod(), 2000);
    
// When you need to cancel all your posted runnables just use:
handler.removeCallbacksAndMessages(null);

Solution 13 - Java

More Safety - With Kotlin Coroutine

Most of the answers use Handler but I give a different solution to delay in activity, fragment, view model with Android Lifecycle ext. This way will auto cancel when the lifecycle begins destroyed - avoid leaking the memory or crashed app

In Activity or Fragment:

lifecycleScope.launch { 
  delay(DELAY_MS)
  doSomething()
}

In ViewModel:

viewModelScope.lanch {
  delay(DELAY_MS)
  doSomething()
}

In suspend function: (Kotlin Coroutine)

suspend fun doSomethingAfter(){
    delay(DELAY_MS)
    doSomething()
}

If you get an error with the lifecycleScope not found! - import this dependency to the app gradle file:

implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.0"

Solution 14 - Java

final Handler handler = new Handler(); 
Timer t = new Timer(); 
t.schedule(new TimerTask() { 
    public void run() { 
        handler.post(new Runnable() { 
            public void run() { 
	            //DO SOME ACTIONS HERE , THIS ACTIONS WILL WILL EXECUTE AFTER 5 SECONDS...
            }
        }); 
    } 
}, 5000); 
    

Solution 15 - Java

I suggest the Timer, it allows you to schedule a method to be called on a very specific interval. This will not block your UI, and keep your app resonsive while the method is being executed.

The other option, is the wait(); method, this will block the current thread for the specified length of time. This will cause your UI to stop responding if you do this on the UI thread.

Solution 16 - Java

So there are a few things to consider here as there are so many ways to skin this cat. Although answers have all already been given selected and chosen. I think it's important that this gets revisited with proper coding guidelines to avoid anyone going the wrong direction just because of "majority selected simple answer".

So first let's discuss the simple Post Delayed answer that is the winner selected answer overall in this thread.

A couple of things to consider. After the post delay, you can encounter memory leaks, dead objects, life cycles that have gone away, and more. So handling it properly is important as well. You can do this in a couple of ways.

For sake of modern development, I'll supply in KOTLIN

Here is a simple example of using the UI thread on a callback and confirming that your activity is still alive and well when you hit your callback.

  Handler(Looper.getMainLooper()).postDelayed({
            if(activity != null && activity?.isFinishing == false){
                txtNewInfo.visibility = View.GONE
            }
        }, NEW_INFO_SHOW_TIMEOUT_MS)

However, this is still not perfect as there is no reason to hit your callback if the activity has gone away. so a better way would be to keep a reference to it and remove it's callbacks like this.

    private fun showFacebookStylePlus1NewsFeedOnPushReceived(){
        A35Log.v(TAG, "showFacebookStylePlus1NewsFeedOnPushReceived")
        if(activity != null && activity?.isFinishing == false){
            txtNewInfo.visibility = View.VISIBLE
            mHandler.postDelayed({
                if(activity != null && activity?.isFinishing == false){
                    txtNewInfo.visibility = View.GONE
                }
            }, NEW_INFO_SHOW_TIMEOUT_MS)
        }
    }

and of course handle cleanup on the onPause so it doesn't hit the callback.

    override fun onPause() {
        super.onPause()
        mHandler.removeCallbacks(null)
    }

Now that we have talked through the obvious, let's talk about a cleaner option with modern day coroutines and kotlin :). If you aren't using these yet, you are really missing out.

   fun doActionAfterDelay() 
        launch(UI) {
            delay(MS_TO_DELAY)           
            actionToTake()
        }
    }

or if you want to always do a UI launch on that method you can simply do:

  fun doActionAfterDelay() = launch(UI){ 
      delay(MS_TO_DELAY)           
      actionToTake()
  }

Of course just like the PostDelayed you have to make sure you handle canceling so you can either do the activity checks after the delay call or you can cancel it in the onPause just like the other route.

var mDelayedJob: Job? = null
fun doActionAfterDelay() 
   mDelayedJob = launch(UI) {
            try {
               delay(MS_TO_DELAY)           
               actionToTake()
            }catch(ex: JobCancellationException){
                showFancyToast("Delayed Job canceled", true, FancyToast.ERROR, "Delayed Job canceled: ${ex.message}")
            }
        }
   }
}

//handle cleanup

override fun onPause() {
   super.onPause()
   if(mDelayedJob != null && mDelayedJob!!.isActive) {
      A35Log.v(mClassTag, "canceling delayed job")
      mDelayedJob?.cancel() //this should throw CancelationException in coroutine, you can catch and handle appropriately
   }
}

If you put the launch(UI) into the method signature the job can be assigned in the calling line of code.

so moral of the story is to be safe with your delayed actions, make sure you remove your callbacks, or cancel your jobs and of course confirm you have the right life cycle to touch items on your delay callback complete. The Coroutines also offers cancelable actions.

Also worth noting that you should typically handle the various exceptions that can come with coroutines. For example, a cancelation, an exception, a timeout, whatever you decide to use. Here is a more advanced example if you decide to really start utilizing coroutines.

   mLoadJob = launch(UI){
            try {
                //Applies timeout
                withTimeout(4000) {
                    //Moves to background thread
                    withContext(DefaultDispatcher) {
                        mDeviceModelList.addArrayList(SSDBHelper.getAllDevices())
                    }
                }

                //Continues after async with context above
                showFancyToast("Loading complete", true, FancyToast.SUCCESS)
            }catch(ex: JobCancellationException){
                showFancyToast("Save canceled", true, FancyToast.ERROR, "Save canceled: ${ex.message}")
            }catch (ex: TimeoutCancellationException) {
                showFancyToast("Timed out saving, please try again or press back", true, FancyToast.ERROR, "Timed out saving to database: ${ex.message}")
            }catch(ex: Exception){
                showFancyToast("Error saving to database, please try again or press back", true, FancyToast.ERROR, "Error saving to database: ${ex.message}")
            }
        }

Solution 17 - Java

For a Simple line Handle Post delay, you can do as following :

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        // Do someting
    }
}, 3000);

I hope this helps

Solution 18 - Java

You can make it much cleaner by using the newly introduced lambda expressions:

new Handler().postDelayed(() -> {/*your code here*/}, time);

Solution 19 - Java

You can use this for Simplest Solution:

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        //Write your code here
    }
}, 5000); //Timer is in ms here.

Else, Below can be another clean useful solution:

new Handler().postDelayed(() -> 
{/*Do something here*/}, 
5000); //time in ms

Solution 20 - Java

If you use RxAndroid then thread and error handling becomes much easier. Following code executes after a delay

Observable.timer(delay, TimeUnit.SECONDS)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(aLong -> {
            // Execute code here
        }, Throwable::printStackTrace);

Solution 21 - Java

Using Kotlin, we can achieve by doing the following

Handler().postDelayed({
    // do something after 1000ms 
}, 1000)

Solution 22 - Java

I created simpler method to call this.

public static void CallWithDelay(long miliseconds, final Activity activity, final String methodName)
    {
        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                try {
                    Method method =  activity.getClass().getMethod(methodName);
                    method.invoke(activity);
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }, miliseconds);
    }

To use it, just call : .CallWithDelay(5000, this, "DoSomething");

Solution 23 - Java

Below one works when you get,

> java.lang.RuntimeException: Can't create handler inside thread that > has not called Looper.prepare()

final Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
  @Override
  public void run() {
    //Do something after 100ms
  }
}, 100);

Solution 24 - Java

It's very easy using the CountDownTimer. For more details https://developer.android.com/reference/android/os/CountDownTimer.html

import android.os.CountDownTimer;

// calls onTick every second, finishes after 3 seconds
new CountDownTimer(3000, 1000) { 

   public void onTick(long millisUntilFinished) {
      Log.d("log", millisUntilFinished / 1000);
   }

   public void onFinish() {
      // called after count down is finished
   } 
}.start();

Solution 25 - Java

I like things cleaner: Here is my implementation, inline code to use inside your method

new Handler().postDelayed(new Runnable() {
  @Override
  public void run() {
    //Do something after 100ms
  }
}, 100);

Solution 26 - Java

Here is another tricky way: it won't throw exception when the runnable change UI elements.

public class SimpleDelayAnimation extends Animation implements Animation.AnimationListener {

    Runnable callBack;

    public SimpleDelayAnimation(Runnable runnable, int delayTimeMilli) {
        setDuration(delayTimeMilli);
        callBack = runnable;
        setAnimationListener(this);
    }

    @Override
    public void onAnimationStart(Animation animation) {
        
    }

    @Override
    public void onAnimationEnd(Animation animation) {
        callBack.run();
    }

    @Override
    public void onAnimationRepeat(Animation animation) {

    }
}

You can call the animation like this:

view.startAnimation(new SimpleDelayAnimation(delayRunnable, 500));

Animation can attach to any view.

Solution 27 - Java

everybody seems to forget to clean the Handler before posting a new runnable or message on it. Otherway they could potentially accumulate and cause bad behaviour.

handler.removeMessages(int what);
// Remove any pending posts of messages with code 'what' that are in the message queue.

handler.removeCallbacks(Runnable r)
// Remove any pending posts of Runnable r that are in the message queue.

Solution 28 - Java

Here is the answer in Kotlin you lazy, lazy people:

Handler().postDelayed({
//doSomethingHere()
}, 1000)

Solution 29 - Java

A suitable solution in android:

private static long SLEEP_TIME = 2 // for 2 second
.
.
MyLauncher launcher = new MyLauncher();
			launcher.start();
.
.
private class MyLauncher extends Thread {
		@Override
		/**
		 * Sleep for 2 seconds as you can also change SLEEP_TIME 2 to any. 
		 */
		public void run() {
			try {
				// Sleeping
				Thread.sleep(SLEEP_TIME * 1000);
			} catch (Exception e) {
				Log.e(TAG, e.getMessage());
			}
            //do something you want to do
	       //And your code will be executed after 2 second
		}
	}

Solution 30 - Java

Similar solution but much cleaner to use

Write this function out side of class

fun delay(duration: Long, `do`: () -> Unit) {

    Handler().postDelayed(`do`, duration)

}

Usage:

delay(5000) {
    //Do your work here
}

Solution 31 - Java

In Android, we can write below kotlin code for delay execution of any function

class MainActivity : AppCompatActivity() {

private lateinit var handler: Handler

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    handler= Handler()
    handler.postDelayed({
        doSomething()
    },2000)
}

private fun doSomething() {
    Toast.makeText(this,"Hi! I am Toast Message",Toast.LENGTH_SHORT).show()
}
}

Solution 32 - Java

There are a lot of ways to do this but the best is to use handler like below

long millisecDelay=3000

Handler().postDelayed({
  // do your work here
 },millisecDelay)

Solution 33 - Java

Well, you can always use legacy Thread.sleep() if you are using Java.

new Thread(() -> {

    try {
        Thread.sleep(millis); //delay in milliseconds
    } catch (Exception e) {
        e.printStackTrace();
    }

    yourMethod();

}).start();

The only problem here is that you cannot do any UI updates since its a separate thread.

Solution 34 - Java

  • Kotlin
  • runOnUiThread from a Fragment
  • Timer

example:

Timer().schedule(500) {
    activity?.runOnUiThread {
        // code                                    
    }
}

Solution 35 - Java

Another response (java8) on activity class.

//hide with delay
new Thread(() -> {
    try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}
    this.runOnUiThread(() -> {
        myView.setVisibility(View.GONE);//this run on GUI
    });
}).start();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionaryaxtView Question on Stackoverflow
Solution 1 - JavakontinuityView Answer on Stackoverflow
Solution 2 - JavaJules ColleView Answer on Stackoverflow
Solution 3 - JavaericksonView Answer on Stackoverflow
Solution 4 - JavapomberView Answer on Stackoverflow
Solution 5 - JavaKhemraj SharmaView Answer on Stackoverflow
Solution 6 - JavaHossam GhareebView Answer on Stackoverflow
Solution 7 - JavaaryaxtView Answer on Stackoverflow
Solution 8 - JavaOscarRyzView Answer on Stackoverflow
Solution 9 - JavanoobView Answer on Stackoverflow
Solution 10 - JavacodezjxView Answer on Stackoverflow
Solution 11 - JavaAlecsView Answer on Stackoverflow
Solution 12 - JavavovahostView Answer on Stackoverflow
Solution 13 - JavaWilson TranView Answer on Stackoverflow
Solution 14 - JavaVishnuView Answer on Stackoverflow
Solution 15 - JavaNateView Answer on Stackoverflow
Solution 16 - JavaSamView Answer on Stackoverflow
Solution 17 - JavaMr TView Answer on Stackoverflow
Solution 18 - JavaAlnour AlharinView Answer on Stackoverflow
Solution 19 - JavaCrime_Master_GoGoView Answer on Stackoverflow
Solution 20 - JavaSuptoView Answer on Stackoverflow
Solution 21 - JavaNikhil KatekhayeView Answer on Stackoverflow
Solution 22 - JavaHelmiBView Answer on Stackoverflow
Solution 23 - JavaSazzad Hissain KhanView Answer on Stackoverflow
Solution 24 - JavaAbdul RizwanView Answer on Stackoverflow
Solution 25 - JavaThiagoView Answer on Stackoverflow
Solution 26 - JavacdytobyView Answer on Stackoverflow
Solution 27 - JavaDan AlboteanuView Answer on Stackoverflow
Solution 28 - JavaDaniel WilsonView Answer on Stackoverflow
Solution 29 - JavaFaakhirView Answer on Stackoverflow
Solution 30 - JavaManoharView Answer on Stackoverflow
Solution 31 - JavaAhasanView Answer on Stackoverflow
Solution 32 - JavaShivam YadavView Answer on Stackoverflow
Solution 33 - JavaRoshana PitigalaView Answer on Stackoverflow
Solution 34 - JavanorbDEVView Answer on Stackoverflow
Solution 35 - JavaBarrretttView Answer on Stackoverflow