Cómo llamar a un método después de un retraso en Android

Deseo poder llamar al siguiente método después de un retraso especificado. En el objective c había algo así como:

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

¿Hay un equivalente de este método en Android con Java? Por ejemplo, necesito poder llamar a un método después de 5 segundos.

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

Mejor versión:

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

No podría usar ninguna de las otras respuestas en mi caso. Usé el Timer nativo de Java en su lugar.

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

Nota: Esta respuesta se dio cuando la pregunta no especificaba Android como el contexto. Para obtener una respuesta específica al hilo de la interfaz de usuario de Android, mira aquí.


Parece que la API de Mac OS permite que el hilo actual continúe y progtwig la tarea para que se ejecute de forma asíncrona. En Java, la función equivalente es provista por el paquete java.util.concurrent . No estoy seguro de las limitaciones que Android podría imponer.

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

Para ejecutar algo en el hilo de UI después de 5 segundos:

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

puede usar Handler dentro de 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); } }); 

Gracias por todas las excelentes respuestas, encontré la solución que mejor se adapta a mis necesidades.

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

Si tiene que usar el controlador, pero está en otro hilo, puede usar runonuithread para ejecutar el controlador en el hilo de la interfaz de usuario. Esto te salvará de las Excepciones lanzadas que piden que llames a Looper.Prepare()

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

Parece bastante complicado, pero este es uno de los caminos.

Vea esta demostración:

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

Prefiero usar el método View.postDelayed() , código simple a continuación:

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

Aquí está mi solución más corta:

 new Handler().postDelayed(new Runnable() { @Override public void run() { //Do something after 100ms } }, 100); 
 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); 

Sugiero el temporizador , le permite progtwigr un método para ser llamado en un intervalo muy específico. Esto no bloqueará su UI y mantendrá su aplicación resónica mientras se ejecuta el método.

La otra opción es wait (); método, esto bloqueará el hilo actual durante el período de tiempo especificado. Esto hará que su IU deje de responder si lo hace en el hilo de la IU.

Si está utilizando Android Studio 3.0 y superior, puede usar expresiones lambda. El método callMyMethod() se callMyMethod() después de 2 segundos:

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

En caso de que necesite cancelar todos los ejecutables retrasados:

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

Puedes usar esto para la solución más simple:

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

De lo contrario, a continuación puede ser otra solución limpia y útil:

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

Creé un método más simple para llamar esto.

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

Para usarlo, simplemente llame a: .CallWithDelay(5000, this, "DoSomething");

puedes hacerlo mucho más limpio usando las expresiones lambda recién introducidas:

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

Es muy fácil usar CountDownTimer . Para más detalles, 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(); 

Aquí hay otra manera complicada: no lanzará una excepción cuando los elementos de la interfaz de usuario puedan cambiarse.

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

}

Puedes llamar a la animación así:

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

La animación se puede adjuntar a cualquier vista.

todo el mundo parece olvidarse de limpiar el controlador antes de publicar un nuevo archivo ejecutable o mensaje en él. De lo contrario, podrían acumularse y causar un mal comportamiento.

 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. 

Una solución adecuada en 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 } }