tutorial thread studio runonuithread peticiones hilos ejemplo asynctask asincronos asincronas android multithreading

runonuithread - thread android studio



¿Cómo ejecutar un hilo Runnable en Android a intervalos definidos? (10)

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

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 solo una vez. ¿Por qué?


Creo que para este caso típico, es decir, para ejecutar algo con un intervalo fijo, el Timer es más apropiado. Aquí hay un ejemplo simple:

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 algunas ventajas:

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

Creo que puede mejorar la primera solución de Alex2k8 para una 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, suponga que tv.append("Hello Word") cuesta T milisegundos, luego de que la visualización 500 veces el tiempo de retraso sea 500 * T milisegundos
  • Aumentará retrasado cuando se ejecuta mucho tiempo

3. Solución

Para evitar que Just cambie el orden de postDelayed (), para evitar retrasos:

public void run() { handler.postDelayed(this, 1000); tv.append("Hello World"); }


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 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 solo como un comando que puede enviarse a la cola de mensajes para su ejecución, y el controlador como solo un objeto auxiliar que se utiliza para enviar ese comando.

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


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

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

Por lo tanto, los ejemplos proporcionados por @ alex2k8, aunque funcionan correctamente, no son lo mismo. En caso de que se Handler.post() , no se crean nuevos hilos . Simplemente publique Runnable en el hilo con Handler para ser ejecutado por EDT . Después de eso, EDT solo ejecuta Runnable.run() , nada más.

Recuerde: Runnable != Thread .


Un ejemplo interesante es que puede ver continuamente un contador / cronómetro en un hilo separado. También se muestra la ubicación del GPS. Mientras que la actividad principal, el hilo de la interfaz de usuario 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í:

Ejemplo de hilo que muestra la ubicación del GPS y la hora actual ejecutable junto con el hilo de la interfaz de usuario de main-activity


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 }


Para repetir la tarea puedes usar

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)

Dónde

Tarea siendo el método a ejecutar.

Después del tiempo de ejecución inicial.

( intervalo el tiempo para repetir la ejecución)

En segundo lugar

Y también puede usar CountDownTimer si desea ejecutar un número de 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 llámalo de estas dos 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);


new Handler().postDelayed(new Runnable() { public void run() { // do something... } }, 100);