Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Cómo ejecutar un hilo Runnable en Android?

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 ejecuto esta aplicación, el texto se muestra una sola vez. ¿Por qué?

  • ¿Cómo funciona maximumPoolSize de ThreadPoolExecutor?
  • Manejadores, MessageQueue, Looper, ¿todos ellos se ejecutan en el hilo de interfaz de usuario?
  • Cómo usar notificar y esperar
  • Accediendo simultáneamente a diferentes miembros del mismo objeto en Java
  • Java.lang.RuntimeException: Sólo se puede crear un Looper por subproceso
  • ¿Por qué run () es llamado una sola vez?
  • Cómo actualizar la vista de imagen inmediatamente
  • Cómo utilizar runOnUiThread sin obtener "no puede hacer una referencia estática al método no estático" error de compilador
  • 7 Solutions collect form web for “Cómo ejecutar un hilo Runnable en Android?”

    La solución simple a 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 un hilo normal, por ejemplo (con Runner 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 como un comando que puede enviarse a la cola de mensajes para su ejecución y el manejador como un objeto auxiliar utilizado para enviar ese comando.

    Más detalles aquí http://developer.android.com/reference/android/os/Handler.html

    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, asumir tv.append("Hello Word") costo T milisegundos, después de la pantalla 500 veces el tiempo retrasado es 500 * T milisegundos
    • Aumentará el retraso cuando se ejecuta mucho tiempo

    3. Solución

    Para evitar que simplemente cambiar el orden de postDelayed (), para evitar retraso:

     public void run() { handler.postDelayed(this, 1000); tv.append("Hello World"); } 
     new Handler().postDelayed(new Runnable() { public void run() { // do something... } }, 100); 

    Creo que para este caso típico, es decir, para ejecutar algo con un intervalo fijo, Timer es más apropiado. Aquí hay 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 

    El uso del Timer tiene pocas ventajas:

    • El retardo inicial y el intervalo se pueden especificar fácilmente en los argumentos de la función de schedule
    • El temporizador se puede detener llamando simplemente myTimer.cancel()
    • Si desea tener sólo un subproceso en ejecución, recuerde llamar a myTimer.cancel() antes de programar uno nuevo (si myTimer no es nulo)

    Para repetir la tarea puede utilizar

     new Timer().scheduleAtFixedRate(task, runAfterADelayForFirstTime, repeaingTimeInterval); 

    Llámelo 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 repite después de cada segundo (1000)

    Dónde

    Siendo la tarea el método a ejecutar

    Después de la hora de la ejecución inicial

    ( Intervalo de tiempo para repetir la ejecución)

    En segundo lugar

    Y también puede utilizar CountDownTimer si desea ejecutar un número de Tarea de 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 puede hacerlo con runnable. Crear un método ejecutable como

     Runnable runnable = new Runnable() { @Override public void run() { } }; 

    Y lo llaman 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 
     Handler handler=new Handler(); Runnable r = new Runnable(){ public void run() { tv.append("Hello World"); handler.postDelayed(r, 1000); } }; handler.post(r); 

    Si entiendo correctamente la documentación del método Handler.post ():

    Hace que Runnable r se agregue a la cola de mensajes. El runnable se ejecutará en el subproceso al que está conectado este controlador.

    Así que los ejemplos proporcionados por @ alex2k8, aunque funcionan correctamente, no son los mismos. En caso de que se Handler.post() , no se crean nuevos subprocesos . Sólo poste Runnable al hilo con Handler para ser ejecutado por EDT . Después de eso, EDT sólo ejecuta Runnable.run() , nada más.

    Recuerde: Runnable != Thread .

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.