906

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
}
Gautam
  • 7,868
  • 12
  • 64
  • 105
aryaxt
  • 76,198
  • 92
  • 293
  • 442

35 Answers35

2181

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);

The class to import is android.os.handler.

starball
  • 20,030
  • 7
  • 43
  • 238
Arif Amirani
  • 26,265
  • 3
  • 33
  • 30
  • This worked perfectly and fit right into the method that I needed to do the call from. Thanks. – JT. Mar 28 '12 at 20:10
  • Same here; use it to delay fragment commits to improve animation. –  Jun 11 '12 at 20:44
  • 1
    This may have been the final piece that helped cement Android handler/threading concepts in my head. Excellent :) – loeschg Nov 28 '12 at 16:34
  • 113
    This solution is usefull only on UI thread. Otherwise on normal thread, you need to implement looper which is not the best version I think – olivier_sdg Jan 10 '13 at 14:59
  • 3
    @olivier_sdg why do you need to implement looper? – djechlin Mar 13 '13 at 16:37
  • 41
    @djechlin A Handler must always be linked to a Looper, which will actually process the Runnable you post(). The UI thread already comes with a Looper, so you can just make a new Handler() on the UI thread and post() Runnables directly to it. These Runnables execute on the UI thread. To have Runnables execute on another thread, you need to make a new thread, then Looper.prepare(), make a new Handler() and then Looper.loop(). Any Runnables posted to this new Handler will execute on this new thread. If you don't do all this, the post() will throw an exception. – Dororo Mar 25 '13 at 21:48
  • 14
    In case you need to, you can also **cancel** the execution as long as the Runnable is still in the message queue by calling `removeCallbacks(Runnable r)` on the `Handler`. – Dennis May 27 '14 at 12:24
  • 1
    @olivier_sdg you can use ``Looper.getMainLooper()`` – pomber May 01 '15 at 13:35
  • same demonstrated in a sample app and in emulator https://www.youtube.com/watch?v=LCLO7q2uhOs – Piyush-Ask Any Difference May 15 '15 at 13:55
  • is the `handler` variable needed ? Cant we just do `new Handler().postDelayed` ? – cyrilchampier Sep 23 '15 at 13:03
  • Depending on the use case this one can lead to annoying hiccups if you decide to run it from UI thread, basically `new Handler()` call attaches itself to the CURRENT thread, if it happen to be a main UI thread 2 things are important: you will be able to modify your UI from `run()` but if you try to do something time consuming (network blocking call or db operations) it will block your UI. On the other hand if constructor called from worker thread which don't have Looper associated with it, it won't work. – Max Ch May 13 '16 at 23:27
  • @VioletGiraffe when you need to stop handler from runnable you need to declare it final. – Kyryl Zotov Jun 30 '16 at 11:33
  • Is it okay if I use this approach to have touch feedback on click of an item.. `view.setColor(some_color)` and then remove this color in Handler after `x` seconds...? – eRaisedToX Jun 13 '17 at 09:29
  • @eRaisedToX - yes, you can since `handler.postDelayed(...)` runs inside the UI thread in the answer's code - unless you specify another `Looper` specifically (then should use `runOnUiThread(...)`). – Touhid May 14 '18 at 06:21
  • 2
    I'm using it this way: `new Handler().postDelayed(() -> { //Do something after 100ms }, 100);` – Choletski Sep 27 '18 at 09:19
  • in kotlin, use Handler().postDelayed... (you will get a compile error if you try using Handler.postDelayed unless you're not using camelcase and Handler is a variable of type android.os.Handler) – caitcoo0odes Mar 06 '19 at 22:47
  • can I use 1 handler and call multiple postDelayed() with different runnables on that handler ? – isJulian00 May 27 '19 at 00:48
  • we don't have to put Looper.getMainLooper(); inside when we declare a new runnable ? – isJulian00 May 27 '19 at 01:17
  • is there a blocking delay as well? I think this doesnt work if we want to block the process or background threads. – Raulp Oct 12 '20 at 20:06
  • Java can be just as compact. new Handler(Looper.getMainLooper()).postDelayed(() -> {//Do something after 100 ms },100); – Lehrian Mar 15 '22 at 17:00
371

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);
Jules Colle
  • 11,227
  • 8
  • 60
  • 67
  • 48
    this is better than the ones that use Handler, because it doesn't have Looper issues when the Handler is not run on the UI thread. – Ben H Jun 27 '13 at 19:26
  • 33
    You should keep a reference to your timer in order to cancel it when it's not needed anymore since according to the Android doc: "When a timer is no longer needed, users should call cancel(), which releases the timer's thread and other resources. Timers not explicitly cancelled may hold resources indefinitely." – Pooks Jul 29 '14 at 08:46
  • 18
    Attention! This doesn't run on UI thread. Running this on ui thread caused a Fatal Error: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. – vovahost Oct 28 '15 at 11:29
  • 15
    @vovahost that's only because you are updating UI components inside the timer block – Tim Oct 28 '15 at 11:58
  • Be aware, that timertask will have strange behaviour if you set the system time (you need system permission for that, though) during its execution – BoredT Nov 17 '15 at 11:49
  • 10
    Note that java.util.Timer (and TimerTask) will be deprecated in JDK 9. TimerTask creates new Threads for tasks which is not very good. – Varvara Kalinina Jun 10 '17 at 17:23
  • See also [TimerTask vs Handler](https://stackoverflow.com/questions/20330355/timertask-or-handler) – Suragch Sep 05 '17 at 03:04
  • 4
    @VarvaraKalinina Doesn't look like the Timer and TimerTask are deprecated in Java 9. (https://docs.oracle.com/javase/9/docs/api/java/util/Timer.html). – Stephen M -on strike- Aug 10 '18 at 18:26
  • This is the only solution that has worked for me too. You could add the cancel(); Call inside of your run call. – AD Progress Aug 31 '21 at 12:21
  • is this called every 2 seconds ? or just 1 time called after 2 seconds and not repeatedly @Jules ? – gumuruh Jan 14 '23 at 10:04
  • 1
    @gumuruh just once – Jules Colle Mar 18 '23 at 20:03
188

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);
  ⋮
}
Community
  • 1
  • 1
erickson
  • 265,237
  • 58
  • 395
  • 493
  • 3
    This never calls the Runnable for me – Ky - Mar 17 '14 at 18:25
  • 14
    As a side note: This also allows you to **cancel** the task later, which might be helpful in some situations. Simply store a reference to the `ScheduledFuture>` returned by `worker.schedule()` and call its `cancel(boolean)` method. – Dennis May 27 '14 at 12:14
  • I think this answer is outdated. .schedule doesn't seem to be a method of Runnable any longer...? :/ – beetree Jan 02 '15 at 00:20
  • 5
    @beetree it's a method on `ScheduledExecutorService`. – erickson Jan 02 '15 at 01:01
  • 4
    This does not work if ui thread objects are involved you must call runOnUIThread(new runnable(){ run()....}); or post a runnable using handler object from inside the run(){ } – Jayant Arora Mar 01 '16 at 10:36
  • on Android (running as service), this is the solution that worked for me. – Carlos Barcellos Sep 15 '16 at 16:02
  • Is it okay if I use this approach to have touch feedback on click of an item.. view.setColor(some_color) and then remove this color in scheduler after x seconds...? – eRaisedToX Jun 13 '17 at 09:29
  • @eRaisedToX I think the Android-specific approach using `AsyncTask` would be a good fit for that. – erickson Jun 13 '17 at 17:14
  • it works nicely in android too with some slight tingering and modification –  Jul 28 '17 at 00:25
117

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);
Jared Rummler
  • 37,824
  • 19
  • 133
  • 148
pomber
  • 23,132
  • 10
  • 81
  • 94
53

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);
Khemraj Sharma
  • 57,232
  • 27
  • 203
  • 212
  • 1
    @JanRabe Thanks for your suggestion. I appriciate it. However question is `How to call a method after a delay in Android`. So I focued on that. To the point. Otherwise java leaks is a big topic to understand seperately for developers. – Khemraj Sharma Jul 24 '19 at 10:17
  • 1
    `Handler().postDelayed({ }, 2000)` shows as depricated – Tim Jun 23 '21 at 03:32
45

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);           
    }
});
Ole Pannier
  • 3,208
  • 9
  • 22
  • 33
Hossam Ghareeb
  • 7,063
  • 3
  • 53
  • 64
40

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
    }
}
Jared Rummler
  • 37,824
  • 19
  • 133
  • 148
aryaxt
  • 76,198
  • 92
  • 293
  • 442
  • Is it okay if I use this approach to have touch feedback on click of an item.. view.setColor(some_color) and then remove this color in Handler after x seconds...? – eRaisedToX Jun 13 '17 at 09:30
25

More Safety - With Kotlin Coroutine

Most of the answers use Handler, but I provide a different solution to handle delays in activity, fragment, and view model using Android Lifecycle extensions. This approach will automatically cancel when the lifecycle is destroyed, avoiding memory leaks or app crashes

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"
Wilson Tran
  • 4,050
  • 3
  • 22
  • 31
  • 3
    I think the coroutine approach is better. Especially when you have the scope bounded with component Activity, Fragment, Custom Component with the lifecycle. Most of the time the requirement is to execute a method while the host is alive. I would also suggest getting the Job instance to support logical cancellation. For example: val job = scope.launch {....} .... .... // Cancel the delay job before it starts execution job.cancel() – S.Javed Jan 10 '21 at 22:30
23

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?");
     }
}
OscarRyz
  • 196,001
  • 113
  • 385
  • 569
21

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.

0xC0DED00D
  • 19,522
  • 20
  • 117
  • 184
  • 4
    This works, I can't edit your post because of stupid SO rules with minimum 6 characters to edit, but there is '()' missing after 'new Handler' it should be 'new Handler()' – Jonathan Muller Feb 09 '15 at 16:17
  • 2
    Instead of placing everything into the UI thread, you can do : new Handler(Looper.getMainLooper()) – Tobliug Mar 18 '15 at 02:30
19

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

mView.postDelayed(new Runnable() {
    @Override
    public void run() {
        // Do something after 1000 ms
    }
}, 1000);
Alexander Farber
  • 21,519
  • 75
  • 241
  • 416
codezjx
  • 9,012
  • 5
  • 47
  • 57
15

Here is my shortest solution:

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        //Do something after 100ms
    }
}, 100);
Tunaki
  • 132,869
  • 46
  • 340
  • 423
Alecs
  • 2,900
  • 1
  • 22
  • 25
13

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);
vovahost
  • 34,185
  • 17
  • 113
  • 116
10
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); 
Jared Rummler
  • 37,824
  • 19
  • 133
  • 148
Vishnu
  • 1,029
  • 4
  • 14
  • 24
7

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.

Nate
  • 30,286
  • 23
  • 113
  • 184
  • 2
    Thread.sleep() is better than Object.wait(). Wait implies you expect to be notified and are synchronizing around some activity. Sleep indicates that you simply wish to do nothing for some specified time. Timer is the way to go if you want the action to happen asynchronously at some later point in time. – Tim Bender Jun 18 '10 at 18:51
  • 1
    That is true. Thats why I listed it as another option ;-) – Nate Jun 18 '10 at 19:02
7

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}")
            }
        }
Sam
  • 5,342
  • 1
  • 23
  • 39
  • 1
    No problem Rajiv, I would take it one step further and mention that using Live Data the coroutines can be life cycle aware and self canceling to avoid the cleanup calls, but don't want to throw too many learning curves into one answer ;) – Sam Nov 08 '18 at 14:27
6

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

Mr T
  • 1,409
  • 1
  • 17
  • 24
5

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

new Handler().postDelayed(() -> {/*your code here*/}, time);
Pang
  • 9,564
  • 146
  • 81
  • 122
Alnour Alharin
  • 320
  • 3
  • 13
5

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
Crime_Master_GoGo
  • 1,641
  • 1
  • 20
  • 30
4

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);
Rahul Gaur
  • 1,661
  • 1
  • 13
  • 29
Ashik
  • 1,035
  • 12
  • 15
4

Using Kotlin, we can achieve by doing the following

Handler().postDelayed({
    // do something after 1000ms 
}, 1000)
Samuel Liew
  • 76,741
  • 107
  • 159
  • 260
Nikhil Katekhaye
  • 2,344
  • 1
  • 18
  • 19
3

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");

HelmiB
  • 12,303
  • 5
  • 41
  • 68
3

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);
Sazzad Hissain Khan
  • 37,929
  • 33
  • 189
  • 256
2

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();
tronman
  • 9,862
  • 10
  • 46
  • 61
Abdul Rizwan
  • 3,904
  • 32
  • 31
2

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);
Thiago
  • 12,778
  • 14
  • 93
  • 110
1

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.

Pang
  • 9,564
  • 146
  • 81
  • 122
cdytoby
  • 839
  • 10
  • 26
1

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.
Dan Alboteanu
  • 9,404
  • 1
  • 52
  • 40
1

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

Handler().postDelayed({
//doSomethingHere()
}, 1000)
Daniel Wilson
  • 18,838
  • 12
  • 85
  • 135
1
  • Kotlin
  • runOnUiThread from a Fragment
  • Timer

example:

Timer().schedule(500) {
    activity?.runOnUiThread {
        // code                                    
    }
}
norbDEV
  • 4,795
  • 2
  • 37
  • 28
0

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
        }
    }
Fakhar
  • 3,946
  • 39
  • 35
0

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
}
Manohar
  • 22,116
  • 9
  • 108
  • 144
0

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()
}
}
Ahasan
  • 41
  • 5
0

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)
Shivam Yadav
  • 958
  • 11
  • 23
0

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.

Roshana Pitigala
  • 8,437
  • 8
  • 49
  • 80
0

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();
Barrrettt
  • 645
  • 7
  • 15