Conceptos básicos de Android: ejecutar código en el hilo de la interfaz de usuario

En el punto de vista de ejecutar código en el hilo de UI, ¿hay alguna diferencia entre:

MainActivity.this.runOnUiThread(new Runnable() { public void run() { Log.d("UI thread", "I am the UI thread"); } }); 

o

 MainActivity.this.myView.post(new Runnable() { public void run() { Log.d("UI thread", "I am the UI thread"); } }); 

y

 private class BackgroundTask extends AsyncTask { protected void onPostExecute(Bitmap result) { Log.d("UI thread", "I am the UI thread"); } } 

Ninguno de ellos es exactamente el mismo, aunque todos tendrán el mismo efecto neto.

La diferencia entre el primero y el segundo es que si usted está en el hilo principal de la aplicación cuando ejecuta el código, el primero ( runOnUiThread() ) ejecutará Runnable inmediatamente. El segundo ( post() ) siempre pone el Runnable al final de la cola de eventos, incluso si ya está en el hilo principal de la aplicación.

El tercero, suponiendo que crees y ejecutes una instancia de BackgroundTask , doInBackground() mucho tiempo al capturar un hilo del grupo de subprocesos, para ejecutar un doInBackground() no doInBackground() , antes de eventualmente hacer lo que equivale a una post() . Este es de lejos el menos eficiente de los tres. Use AsyncTask si realmente tiene trabajo que hacer en un hilo de fondo, no solo para el uso de onPostExecute() .

Me gusta el comentario de HPP , se puede usar en cualquier lugar sin ningún parámetro:

 new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { Log.d("UI thread", "I am the UI thread"); } }); 

Hay una cuarta forma de usar Handler

 new Handler().post(new Runnable() { @Override public void run() { // Code here will run in UI thread } }); 

La respuesta de Pomber es aceptable, sin embargo, no soy un gran fanático de crear nuevos objetos repetidamente. Las mejores soluciones son siempre las que intentan mitigar la memoria de cerdo. Sí, existe la recolección automática de basura, pero la conservación de la memoria en un dispositivo móvil se encuentra dentro de los límites de las mejores prácticas. El siguiente código actualiza un TextView en un servicio.

 TextViewUpdater textViewUpdater = new TextViewUpdater(); Handler textViewUpdaterHandler = new Handler(Looper.getMainLooper()); private class TextViewUpdater implements Runnable{ private String txt; @Override public void run() { searchResultTextView.setText(txt); } public void setText(String txt){ this.txt = txt; } } 

Se puede usar desde cualquier lugar como este:

 textViewUpdater.setText("Hello"); textViewUpdaterHandler.post(textViewUpdater); 

Si necesita usar Fragment, debe usar

 private Context context; @Override public void onAttach(Context context) { super.onAttach(context); this.context = context; } ((MainActivity)context).runOnUiThread(new Runnable() { public void run() { Log.d("UI thread", "I am the UI thread"); } }); 

en lugar de

 getActivity().runOnUiThread(new Runnable() { public void run() { Log.d("UI thread", "I am the UI thread"); } }); 

Porque habrá una excepción de puntero nulo en alguna situación como fragmento de buscapersonas

hola chicos esta es una pregunta básica de cualquier manera que cuento

usar el controlador

 new Handler().post(new Runnable() { @Override public void run() { // Code here will run in UI thread } }); 

A partir de Android P puede usar getMainExecutor() :

 getMainExecutor().execute(new Runnable() { @Override public void run() { // Code will run on the main thread } }); 

De los documentos para desarrolladores de Android :

Devuelve un ejecutor que ejecutará tareas en cola en el hilo principal asociado con este contexto. Este es el hilo usado para enviar llamadas a los componentes de la aplicación (actividades, servicios, etc.).

De los CommonsBlog :

Puede llamar a getMainExcutor () en el contexto para obtener un ejecutor que ejecutará sus trabajos en el hilo principal de la aplicación. Hay otras maneras de lograr esto, utilizando Looper y una implementación Ejecutor personalizada, pero esto es más simple.