Cómo pausar / sleep thread o procesar 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 digamos 1 segundo, necesito volver al estado anterior del botón cambiando 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 necesito pausar?

También lo he intentado (pero no funciona):

new Reminder(5);

Con esto:

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

Author: hichris123, 2009-10-05

9 answers

Una solución a este problema es usar el Controlador .Método 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 causa una fuga 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 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 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 el Runnableutiliza una WeakReference a la Actividad, que es necesaria en una clase estática que necesita acceso a la interfaz de usuario.

 418
Author: tronman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-10 20:06:14

Puedes probar este es corto

SystemClock.sleep(7000);

ADVERTENCIA : Nunca, nunca, haga esto en un subproceso de interfaz de usuario.

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


La solución completa para su problema será: Esto 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 el Controlador tmp. También esta solución es mejor que @tronman porque no retenemos la vista por el Controlador. También no tenemos problema con el Controlador creado en el hilo malo ;)

Documentación

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

Añadido en el nivel de API 1

Espera un número dado de milisegundos (de uptimeMillis) antes de regresar. Similar a sleep (long), pero no arroja InterrumpedException ; los eventos interrupt() se posponen hasta que siguiente operación interrumpible. no devuelve 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:

/**
 * <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;
}
 170
Author: Dawid Drozd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-25 08:54:08

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();
    }
  }
});
 24
Author: Byt3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-26 22:27:43

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

Otra posibilidad es usar un Manejador . Hay un tutorial sobre alguien que cambió de usar un temporizador a usando un Manejador.

Por cierto, no se puede pausar un proceso. Un proceso Java (o Android) tiene al menos 1 subproceso, y solo puedes suspender subprocesos.

 16
Author: Daniel Yankowsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-05 16:01:52

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(); 
 10
Author: vudandroid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-24 17:34:01

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); 
    }
 9
Author: Hubert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-17 05:09:17

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 retraso. Ejecuta el Runnable después de ese retraso.

 8
Author: CommonsWare,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-28 07:41:32

Este es mi ejemplo

Crear un Java Utils

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

        }

    }    
 4
Author: Stefano,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-25 14:29:23

O podrías usar:

android.os.SystemClock.sleep(checkEvery)

Que tiene la ventaja de no requerir una envoltura try ... catch.

 1
Author: aaaa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-06 19:37:45