Cómo pausar / dormir hilo o proceso en Android?

Quiero hacer una pausa entre dos líneas de código, Permítanme explicar un poco:

-> el usuario hace clic en un botón (una tarjeta de hecho) y lo muestro cambiando el fondo de este botón:

thisbutton.setBackgroundResource(R.drawable.icon); 

-> después de que digamos 1 segundo, necesito volver al estado anterior del botón cambiando detrás su fondo:

 thisbutton.setBackgroundResource(R.drawable.defaultcard); 

-> He intentado pausar el hilo entre estas dos líneas de código con:

 try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } 

Sin embargo, esto no funciona. Tal vez es el proceso y no el hilo que tengo que hacer una pausa?

También he intentado (pero no funciona):

 new Reminder(5); 

Con este:

 public class Reminder { Timer timer; public Reminder(int seconds) { timer = new Timer(); timer.schedule(new RemindTask(), seconds*1000); } class RemindTask extends TimerTask { public void run() { System.out.format("Time's up!%n"); timer.cancel(); //Terminate the timer thread } } } 

¿Cómo puedo pausar / dormir el hilo o proceso?

Una buena solución a este problema es utilizar el método Handler.postDelayed () . Sin embargo, la solución siguiente provoca una pérdida de memoria porque utiliza una clase interna y anónima no estática que implícitamente contiene una referencia a su clase externa, la actividad. Esto es un problema cuando se supone que el contexto de la actividad se ha recogido:

 @Override public void onClick(View v) { my_button.setBackgroundResource(R.drawable.icon); // This solution will leak memory! Don't use!!! Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { my_button.setBackgroundResource(R.drawable.defaultcard); } }, 2000); } 

Una solución mejor subclases el Handler y Runnable con clases internas estáticas dentro de la actividad ya que las clases internas estáticas no tienen una referencia implícita a su clase externa:

 private static class MyHandler extends Handler {} private final MyHandler mHandler = new MyHandler(); public static class MyRunnable implements Runnable { private final WeakReference<Activity> mActivity; public MyRunnable(Activity activity) { mActivity = new WeakReference<>(activity); } @Override public void run() { Activity activity = mActivity.get(); if (activity != null) { Button btn = (Button) activity.findViewById(R.id.button); btn.setBackgroundResource(R.drawable.defaultcard); } } } private MyRunnable mRunnable = new MyRunnable(this); public void onClick(View view) { my_button.setBackgroundResource(R.drawable.icon); // Execute the Runnable in 2 seconds mHandler.postDelayed(mRunnable, 2000); } 

Tenga en cuenta que Runnable utiliza una WeakReference a la actividad, que es necesaria en una clase estática que necesita acceso a la interfaz de usuario.

Puedes probar éste es corto

 SystemClock.sleep(7000); 

ADVERTENCIA : Nunca, nunca, hacer esto en un hilo de interfaz de usuario.

Use esto para dormir, por ejemplo. Hilo de fondo


Solución completa para su problema será: Esta es la API disponible 1

 findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View button) { button.setBackgroundResource(R.drawable.avatar_dead); final long changeTime = 1000L; button.postDelayed(new Runnable() { @Override public void run() { button.setBackgroundResource(R.drawable.avatar_small); } }, changeTime); } }); 

Sin crear tmp Handler. También esta solución es mejor que @tronman porque no conservamos la vista por Handler. También no tenemos problema con el manipulador creado en el hilo malo;)

Documentación

Public staid void sleep (ms largo)

Añadido en API nivel 1

Espera un número dado de milisegundos (de uptimeMillis) antes de volver. Similar al sueño (largo), pero no lanza InterruptedException ; Los eventos de interrupción () se diferirán hasta la siguiente operación interrumpible. No vuelve hasta que haya transcurrido al menos el número especificado de milisegundos.

Parámetros

Ms para dormir antes de regresar, en milisegundos de tiempo de actividad.

Código para postDelayed de la clase View:

 /** * <p>Causes the Runnable to be added to the message queue, to be run * after the specified amount of time elapses. * The runnable will be run on the user interface thread.</p> * * @param action The Runnable that will be executed. * @param delayMillis The delay (in milliseconds) until the Runnable * will be executed. * * @return true if the Runnable was successfully placed in to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. Note that a * result of true does not mean the Runnable will be processed -- * if the looper is quit before the delivery time of the message * occurs then the message will be dropped. * * @see #post * @see #removeCallbacks */ public boolean postDelayed(Runnable action, long delayMillis) { final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) { return attachInfo.mHandler.postDelayed(action, delayMillis); } // Assume that post will succeed later ViewRootImpl.getRunQueue().postDelayed(action, delayMillis); return true; } 

Yo uso esto:

 Thread closeActivity = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(3000); // Do some stuff } catch (Exception e) { e.getLocalizedMessage(); } } }); 

Probablemente no quieras hacerlo de esa manera. Al poner un sleep() explícito en su controlador de eventos pulsado por botón, realmente bloquearía toda la interfaz de usuario durante un segundo. Una alternativa es utilizar algún tipo de Timer de un solo disparo. Cree una TimerTask para cambiar el color de fondo de nuevo al color predeterminado y programarlo en el temporizador.

Otra posibilidad es utilizar un Handler . Hay un tutorial sobre alguien que pasó de usar un temporizador a usar un manejador.

Por cierto, no se puede detener un proceso. Un proceso de Java (o Android) tiene al menos 1 subproceso y sólo puede dormir subprocesos.

Esto es lo que hice al final del día – funciona bien ahora:

 @Override public void onClick(View v) { my_button.setBackgroundResource(R.drawable.icon); // SLEEP 2 SECONDS HERE ... final Handler handler = new Handler(); Timer t = new Timer(); t.schedule(new TimerTask() { public void run() { handler.post(new Runnable() { public void run() { my_button.setBackgroundResource(R.drawable.defaultcard); } }); } }, 2000); } 

Además de las respuestas del Sr. Yankowsky, también podría usar postDelayed() . Esto está disponible en cualquier View (por ejemplo, su tarjeta) y toma un Runnable y un período de demora. Ejecuta el Runnable después de ese retraso.

Yo uso CountDownTime

 new CountDownTimer(5000, 1000) { @Override public void onTick(long millisUntilFinished) { // do something after 1s } @Override public void onFinish() { // do something end times 5s } }.start(); 

Este es mi ejemplo

Crear un Utilitario Java

  import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; public class Utils { public static void showDummyWaitingDialog(final Context context, final Intent startingIntent) { // ... final ProgressDialog progressDialog = ProgressDialog.show(context, "Please wait...", "Loading data ...", true); new Thread() { public void run() { try{ // Do some work here sleep(5000); } catch (Exception e) { } // start next intent new Thread() { public void run() { // Dismiss the Dialog progressDialog.dismiss(); // start selected activity if ( startingIntent != null) context.startActivity(startingIntent); } }.start(); } }.start(); } } 
  • Android.app.SuperNotCalledException: La actividad no ha llamado a super.onStop ()
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.