¿Cómo ejecutar un hilo ejecutable en Android a intervalos definidos?
Desarrollé una aplicación para mostrar texto a intervalos definidos en la pantalla del emulador de Android. Estoy usando la clase Handler
. Aquí hay un fragmento de mi código:
handler = new Handler();
Runnable r = new Runnable() {
public void run() {
tv.append("Hello World");
}
};
handler.postDelayed(r, 1000);
Cuando corro esta aplicación el texto se muestra solo una vez. ¿Por qué?
10 answers
La solución simple para su ejemplo es:
handler = new Handler();
final Runnable r = new Runnable() {
public void run() {
tv.append("Hello World");
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(r, 1000);
O podemos usar hilo normal por ejemplo (con el corredor original) :
Thread thread = new Thread() {
@Override
public void run() {
try {
while(true) {
sleep(1000);
handler.post(this);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
Puede considerar su objeto ejecutable solo como un comando que se puede enviar a la cola de mensajes para su ejecución, y handler como solo un objeto auxiliar utilizado para enviar ese comando.
Más detalles aquí http://developer.android.com/reference/android/os/Handler.html
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
2015-04-24 15:50:50
Creo que puede mejorar la primera solución de Alex2k8 para la actualización correcta cada segundo
1.Código original:
public void run() {
tv.append("Hello World");
handler.postDelayed(this, 1000);
}
2.Análisis
- En el costo anterior, asuma
tv.append("Hello Word")
costo T milisegundos, después de la visualización 500 tiempos de retraso el tiempo es 500 * T milisegundos - Se incrementará retrasado cuando se ejecute mucho tiempo
3. Solución
Para evitar que Solo cambie el orden de postDelayed (), para evitar retrasado:
public void run() {
handler.postDelayed(this, 1000);
tv.append("Hello World");
}
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-12-15 13:47:02
new Handler().postDelayed(new Runnable() {
public void run() {
// do something...
}
}, 100);
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
2017-06-23 19:25:38
Creo que para este caso típico, es decir, ejecutar algo con un intervalo fijo, Timer
es más apropiado. He aquí un ejemplo sencillo:
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
@Override
public void run() {
// If you want to modify a view in your Activity
MyActivity.this.runOnUiThread(new Runnable()
public void run(){
tv.append("Hello World");
});
}
}, 1000, 1000); // initial delay 1 second, interval 1 second
Usar Timer
tiene pocas ventajas:
- El retraso inicial y el intervalo se pueden especificar fácilmente en los argumentos de la función
schedule
- El temporizador se puede detener simplemente llamando a
myTimer.cancel()
- Si desea tener un solo subproceso en ejecución, recuerde llamar
myTimer.cancel()
antes de programar una nueva (si myTimer no es null)
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-12-15 15:45:14
Para repetir la tarea se puede utilizar
new Timer().scheduleAtFixedRate(task, runAfterADelayForFirstTime, repeaingTimeInterval);
Llámalo como
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
}
},500,1000);
El código anterior se ejecutará por primera vez después de medio segundo(500) y se repetirá después de cada segundo(1000)
Donde
Task siendo el método a ejecutar
Después de el tiempo para la ejecución inicial
(intervalo el tiempo para repetir la ejecución)
En segundo lugar
Y también puedes utilice CountDownTimer si desea ejecutar una tarea varias veces.
new CountDownTimer(40000, 1000) { //40000 milli seconds is total time, 1000 milli seconds is time interval
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
}
}.start();
//Above codes run 40 times after each second
Y también puedes hacerlo con runnable. crear un método ejecutable como
Runnable runnable = new Runnable()
{
@Override
public void run()
{
}
};
Y llamarlo de ambas maneras
new Handler().postDelayed(runnable, 500 );//where 500 is delayMillis // to work on mainThread
O
new Thread(runnable).start();//to work in Background
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-06-17 05:46:27
Handler handler=new Handler();
Runnable r = new Runnable(){
public void run() {
tv.append("Hello World");
handler.postDelayed(r, 1000);
}
};
handler.post(r);
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-06-21 18:25:16
Si entiendo correctamente la documentación de Handler.método post ():
Hace que la r ejecutable se agregue a la cola de mensajes. El runnable se ejecutará en el hilo al que está unido este controlador.
Así que los ejemplos proporcionados por @alex2k8, aunque funcionan correctamente, no son los mismos.
En caso de que se use Handler.post()
, no se crean nuevos hilos. Usted acaba de publicar Runnable
en el hilo con Handler
para ser ejecutado por EDT.
Después de eso, EDT solo ejecuta Runnable.run()
, nada más.
Recuerda:
Runnable != Thread
.
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-10-08 21:44:59
Un ejemplo interesante es que puedes ver continuamente un contador/cronómetro corriendo en subprocesos separados. También muestra la ubicación GPS. Mientras que el hilo de la interfaz de usuario de la actividad principal ya está allí.
Extracto:
try {
cnt++; scnt++;
now=System.currentTimeMillis();
r=rand.nextInt(6); r++;
loc=lm.getLastKnownLocation(best);
if(loc!=null) {
lat=loc.getLatitude();
lng=loc.getLongitude();
}
Thread.sleep(100);
handler.sendMessage(handler.obtainMessage());
} catch (InterruptedException e) {
Toast.makeText(this, "Error="+e.toString(), Toast.LENGTH_LONG).show();
}
Para ver el código ver aquí:
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
2017-08-25 16:46:02
Ahora en Kotlin puedes ejecutar hilos de esta manera:
class SimpleRunnable: Runnable {
public override fun run() {
println("${Thread.currentThread()} has run.")
}
}
fun main(args: Array<String>) {
val thread = SimpleThread()
thread.start() // Will output: Thread[Thread-0,5,main] has run.
val runnable = SimpleRunnable()
val thread1 = Thread(runnable)
thread1.start() // Will output: Thread[Thread-1,5,main] has run
}
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-07-25 18:25:11
Kotlin
private lateinit var runnable: Runnable
override fun onCreate(savedInstanceState: Bundle?) {
val handler = Handler()
runnable = Runnable {
handler.postDelayed(runnable, 2000)
}
handler.postDelayed(runnable, 2000)
}
Java
Runnable runnable;
Handler handler;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
handler = new Handler();
runnable = new Runnable() {
@Override
public void run() {
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(runnable, 1000);
}
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-09-21 13:29:45