¿Cómo pausar / suspender el hilo o procesar en Android?

Quiero hacer una pausa entre dos líneas de código, déjame 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 digamos 1 segundo, necesito volver al estado anterior del botón cambiando su fondo:

 thisbutton.setBackgroundResource(R.drawable.defaultcard); 

-> He intentado detener 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 lo que necesito para hacer una pausa?

También lo intenté (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 detener / suspender el hilo o el proceso?

Una solución a este problema es usar el método Handler.postDelayed () . Algunos materiales de capacitación de Google sugieren la misma solución.

 @Override public void onClick(View v) { my_button.setBackgroundResource(R.drawable.icon); Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { my_button.setBackgroundResource(R.drawable.defaultcard); } }, 2000); } 

Sin embargo, algunos han señalado que la solución anterior provoca una pérdida de memoria porque utiliza una clase interna y anónima no estática que contiene implícitamente una referencia a su clase externa, la actividad. Este es un problema cuando el contexto de actividad es basura recolectada.

Una solución más compleja que evita las subclases de pérdida de memoria 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 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 para la actividad, que es necesaria en una clase estática que necesita acceso a la interfaz de usuario.

Puedes probar este, es corto

 SystemClock.sleep(7000); 

ADVERTENCIA : nunca, nunca, haga esto en un hilo de IU.

Use esto para dormir, por ej. hilo de fondo.


La solución completa para su problema será: Esta es 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. Además, esta solución es mejor que @tronman porque no conservamos la vista por parte de Handler. Además, no tenemos problemas con el controlador creado en el hilo malo;)

Documentación

sueño vacío público estático (ms largo)

Agregado en el nivel de API 1

Espera un número dado de milisegundos (de tiempo de actividad de Milis) antes de regresar. Similar a dormir (largo), pero no lanza InterruptedException ; Los eventos de interrupt () se aplazan hasta la siguiente operación de interrupción. No regresa 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 from View class:

 /** * 

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.

* * @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 sleep() en su controlador de eventos con botón, en realidad bloquearía toda la interfaz de usuario por un segundo. Una alternativa es usar algún tipo de temporizador de disparo único. Cree un TimerTask para cambiar el color de fondo al color predeterminado y progtwigrlo en el temporizador.

Otra posibilidad es usar un controlador . Hay un tutorial sobre alguien que cambió el uso de un temporizador a usar un controlador.

Por cierto, no puedes pausar un proceso. Un proceso de Java (o Android) tiene al menos 1 hilo y solo puede suspender los hilos.

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

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 postDelayed() usar postDelayed() . Esto está disponible en cualquier View (por ejemplo, su tarjeta) y tiene un Runnable y un período de retraso. Ejecuta Runnable después de ese retraso.

Este es mi ejemplo

Crear un Util de 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(); } } 

O podrías usar:

 android.os.SystemClock.sleep(checkEvery) 

que tiene la ventaja de no requerir un ajuste de envoltura try ... catch .