¿Cuál es el equivalente a un setInterval / setTimeout de JavaScript en Android / Java?


129

¿Alguien puede decirme si existe un equivalente para setInterval / setTimeout para Android? ¿Alguien tiene algún ejemplo sobre cómo hacerlo?

Respuestas:


245

Como siempre con Android, hay muchas maneras de hacer esto, pero suponiendo que simplemente quieras ejecutar un fragmento de código un poco más tarde en el mismo hilo, utilizo esto:

new android.os.Handler().postDelayed(
    new Runnable() {
        public void run() {
            Log.i("tag", "This'll run 300 milliseconds later");
        }
    }, 
300);

.. esto es más o menos equivalente a

setTimeout( 
    function() {
        console.log("This will run 300 milliseconds later");
    },
300);

Esta es una muy buena solución para la selección de cajones y la
transacción de

66
¿Cómo puedo cancelarlo si lo necesito?
Quentin Roy

¿Cómo se obtiene el alcance de la actividad dentro del método run ()?
Andy

@Andy así:MyActivityName.this.myFunctionOnActivity()
Ben Clayton

1
@QuentinRoy: Handler timeout = new Handler(); final Runnable r = new Runnable{...}; timeout.postDelayed(r, 300);y si quieres cancelarlo:timeout.removeCallbacks(r);
Bastian Springer el

101

setInterval ()

función que se repite cada n milisegundos

Javascript

 setInterval(function(){ Console.log("A Kiss every 5 seconds"); }, 5000);

Equivalente aproximado de Java

new Timer().scheduleAtFixedRate(new TimerTask(){
    @Override
    public void run(){
       Log.i("tag", "A Kiss every 5 seconds");
    }
},0,5000);

setTimeout ()

función que funciona solo después de n milisegundos

Javascript

setTimeout(function(){ Console.log("A Kiss after 5 seconds"); },5000);

Equivalente aproximado de Java

new android.os.Handler().postDelayed(
    new Runnable() {
        public void run() {
            Log.i("tag","A Kiss after 5 seconds");
        }
}, 5000);

55
Para el scheduleAtFixedRatemétodo, ¿cómo cancela el temporizador dentro de la actividad una vez que la actividad ha terminado?
auroranil

2
@ user824294 puede guardar su instancia de Timer en una variable y llamar a "cancel ()" cuando desee detener las tareas programadas - Timer t = new Timer (); t.scheduleAtFixedRate (...); - Y luego llame a t.cancel (); cuando quieras
Aebsubis

14

Si no le preocupa despertar su teléfono o recuperar su aplicación de la muerte, intente:

// Param is optional, to run task on UI thread.     
Handler handler = new Handler(Looper.getMainLooper());
Runnable runnable = new Runnable() {
    @Override
    public void run() {
        // Do the task...
        handler.postDelayed(this, milliseconds) // Optional, to repeat the task.
    }
};
handler.postDelayed(runnable, milliseconds);

// Stop a repeating task like this.
handler.removeCallbacks(runnable);

En mi teléfono (Huawei P Smart), el controlador no activa el dispositivo desde el modo de suspensión ( como lo observó apanloco en otra respuesta )
Franco

13

Dependiendo de lo que realmente quieras lograr, deberías echar un vistazo a los controladores de Android:

http://developer.android.com/reference/android/os/Handler.html

Si anteriormente utilizó javascript setTimeout (), etc. para programar una tarea para que se ejecute en el futuro, esta es la forma en que Android lo hace (postDelayed / sendMessageDelayed).

Tenga en cuenta que ni Handlers ni Timers hacen que un teléfono Android se active desde el modo de suspensión. En otras palabras, si desea programar algo para que suceda realmente a pesar de que la pantalla está apagada / la CPU está durmiendo, también debe consultar el AlarmManager.


5

No sé mucho sobre JavaScript, pero creo que Timers puede ser lo que estás buscando.

http://developer.android.com/reference/java/util/Timer.html

Desde el enlace:

One-shot está programado para ejecutarse en un tiempo absoluto o después de un retraso relativo. Las tareas recurrentes se programan con un período fijo o una tasa fija.


Nota: Te llama en un hilo de fondo, no en el hilo principal / UI.
Pang

Esta no es una respuesta, sino una referencia a información externa que puede contener o no una solución de OP. ¡Pegue el código relevante que OP puede usar!
Lev

5

La primera respuesta es definitivamente la respuesta correcta y es en lo que basé esta versión lambda, que es mucho más corta en sintaxis. Como Runnable solo tiene 1 método de anulación "run ()", podemos usar un lambda:

this.m_someBoolFlag = false;
new android.os.Handler().postDelayed(() -> this.m_someBoolFlag = true, 300);

5
import java.util.Timer;
import java.util.TimerTask;

class Clock {
    private Timer mTimer = new Timer();

    private int mSecondsPassed = 0;
    private TimerTask mTask = new TimerTask() {
        @Override
        public void run() {
            mSecondsPassed++;
            System.out.println("Seconds passed: " + mSecondsPassed);
        }
    };

    private void start() {
        mTimer.scheduleAtFixedRate(mTask, 1000, 1000);
    }

    public static void main(String[] args) {
        Clock c = new Clock();
        c.start();
    }
}

4

Aquí hay un setTimeout equivalente, principalmente útil cuando se trata de actualizar la interfaz de usuario después de un retraso.

Como ya sabrás, la actualización de la interfaz de usuario solo puede hacerse desde el hilo de la interfaz de usuario. AsyncTask lo hace por usted llamando a su método onPostExecute desde ese hilo.

new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
            }

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            // Update the User Interface
        }

    }.execute();

3
1. Del mismo modo, onProgressUpdate()también se puede utilizar para simular setInterval(). 2. AsyncTask ejecuta en un grupo de subprocesos (o simplemente un solo hilo), por lo que a. puede que tenga que esperar hasta que otro AsyncTasktermine; b . ocupará un hilo del grupo.
Pang

Hay muchos problemas al usar la tarea asíncrona en este contexto (solo un subproceso y el bloqueo de un subproceso sin ninguna razón); las otras soluciones son mucho mejores.
Elemental

4

Estaba creando un reproductor de mp3 para Android, quería actualizar la hora actual cada 500 ms, así que lo hice así

setInterval

private void update() {
    new android.os.Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            long cur = player.getCurrentPosition();
            long dur = player.getDuration();
            currentTime = millisecondsToTime(cur);
            currentTimeView.setText(currentTime);
            if (cur < dur) {
                updatePlayer();
            }

            // update seekbar
            seekBar.setProgress( (int) Math.round((float)cur / (float)dur * 100f));
        }
    }, 500);
}

que llama al mismo método de forma recursiva

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.