Home » Java » How to call a method after a delay in Android

How to call a method after a delay in Android

Posted by: admin November 2, 2017 Leave a comment

Questions:

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
}
Answers:

Better version:

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

Questions:
Answers:

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

Questions:
Answers:

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

Questions:
Answers:

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

Questions:
Answers:

you can use Handler inside UIThread:

runOnUiThread(new Runnable() {

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

    }
});

Questions:
Answers:

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
    }
}

Questions:
Answers:

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.

Questions:
Answers:

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

Questions:
Answers:

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

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

Questions:
Answers:
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); 

Questions:
Answers:

Here is my shortest solution:

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

Questions:
Answers:

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.

Questions:
Answers:

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

Questions:
Answers:

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 all the delayed runnables:

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

// When you need to cancel just call:
handler.removeCallbacksAndMessages(null);

Questions:
Answers:

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.

Questions:
Answers:

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

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

Questions:
Answers:

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

Questions:
Answers:

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
        }
    }

Questions:
Answers:

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.