¿Cómo pausar/suspendir hilo o proceso en Android?

Resuelto Hubert asked hace 54 años • 12 respuestas

Quiero hacer una pausa entre dos líneas de código. Déjame explicarte 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);

-> Intenté 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. ¿Quizás sea el proceso y no el hilo lo que necesito pausar?

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 pausar/dormir el hilo o proceso?

Hubert avatar Jan 01 '70 08:01 Hubert
Aceptado

Una solución a este problema es utilizar el método Handler.postDelayed() . Algunos materiales de formació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 implícitamente contiene una referencia a su clase externa, la actividad. Esto es un problema cuando el contexto de la actividad es recolección de basura.

Una solución más compleja que evita la pérdida de memoria subclases Handlery Runnablecon clases internas estáticas dentro de la actividad, ya que las clases internas estáticas no contienen 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 Runnableutiliza una referencia débil a la actividad, que es necesaria en una clase estática que necesita acceso a la interfaz de usuario.

tronman avatar Jun 14 '2010 18:06 tronman

Puedes probar este, es corto.

SystemClock.sleep(7000);

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

Utilice esto para dormir, por ejemplo. hilo de fondo.


La solución completa para su problema será: Esta está disponible API 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 del controlador. Además, no tenemos problemas con el controlador creado en un hilo incorrecto;)

Documentación

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

Agregado en API nivel 1

Espera una cantidad determinada de milisegundos (de uptimeMillis) antes de regresar. Similar a dormir (largo), pero no arroja InterruptedException ; Los eventos de interrupción() se difieren hasta la siguiente operación interrumpible. 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 de la clase Ver:

/**
 * <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;
}
Gelldur avatar Jan 30 '2013 23:01 Gelldur

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();
    }
  }
});
Byt3 avatar Mar 26 '2012 20:03 Byt3