Cómo utilizar runOnUiThread

Estoy aprendiendo a hacer algo en UI-Thread, así que he escrito una actividad de prueba simple. Pero creo que malinterpreté algo, porque cuando hago clic en el botón – la aplicación no está resposing más

public class TestActivity extends Activity { Button btn; int i = 0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btn = (Button)findViewById(R.id.btn); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { runThread(); } }); } private void runThread(){ runOnUiThread (new Thread(new Runnable() { public void run() { while(i++ < 1000){ btn.setText("#"+i); try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } } } })); } } 

A continuación se corrige el runThread función runThread .

 private void runThread() { new Thread() { public void run() { while (i++ < 1000) { try { runOnUiThread(new Runnable() { @Override public void run() { btn.setText("#" + i); } }); Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } 

Sólo envolverlo como una función, a continuación, llamar a esta función de su hilo de fondo.

 public void debugMsg(String msg) { final String str = msg; runOnUiThread(new Runnable() { @Override public void run() { mInfo.setText(str); } }); } 

Lo tienes de regreso. Su clic de botón da como resultado una llamada a runOnUiThread() , pero esto no es necesario, ya que el controlador de clics ya se está ejecutando en el subproceso de la interfaz de usuario. A continuación, su código en runOnUiThread() está iniciando un nuevo subproceso de fondo, donde intenta realizar operaciones de interfaz de usuario, que luego fallan.

En su lugar, sólo tiene que iniciar el subproceso de fondo directamente desde su controlador de clics. A continuación, envuelva las llamadas a btn.setText() dentro de una llamada a runOnUiThread() .

 runOnUiThread(new Runnable() { public void run() { //Do something on UiThread } }); 

Hay varias técnicas que utilizan de runOnUiThread (), permite ver todo

Este es mi hilo principal (hilo de la interfaz de usuario) llamado AndroidBasicThreadActivity y voy a actualizar desde un hilo de trabajo de varias maneras –

 public class AndroidBasicThreadActivity extends AppCompatActivity { public static TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_android_basic_thread); textView = (TextView) findViewById(R.id.textview); MyAndroidThread myTask = new MyAndroidThread(AndroidBasicThreadActivity.this); Thread t1 = new Thread(myTask, "Bajrang"); t1.start(); } } 

1.) Pasando la instancia de Activity como argumento en thread de trabajo

 class MyAndroidThread implements Runnable { Activity activity; public MyAndroidThread(Activity activity) { this.activity = activity; } @Override public void run() { activity.runOnUiThread(new Runnable() { @Override public void run() { AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread."); } }); } } 

2.) Utilizando el método Post (Runnable runnable) de View en el subproceso de trabajo

 class MyAndroidThread implements Runnable { Activity activity; public MyAndroidThread(Activity activity) { this.activity = activity; } @Override public void run() { AndroidBasicThreadActivity.textView.post(new Runnable() { @Override public void run() { AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread."); } }); } } 

3.) Utilizando la clase Handler desde el paquete android.os Si no tenemos el contexto (esto / getApplicationContext ()) o la instancia de la actividad (AndroidBasicThreadActivity.this) entonces tenemos que usar la clase Handler como a continuación –

 class MyAndroidThread implements Runnable { Activity activity; public MyAndroidThread(Activity activity) { this.activity = activity; } @Override public void run() { new Handler(Looper.getMainLooper()).post(new Runnable() { public void run() { AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread."); } }); } } 

Puede utilizar de esta muestra:

En el ejemplo siguiente, vamos a utilizar esta facilidad para publicar el resultado de una búsqueda de sinónimo que fue procesada por un hilo de fondo.

Para lograr el objetivo durante la devolución de llamada de la actividad OnCreate, configuraremos onClickListener para ejecutar searchTask en un subproceso creado.

Cuando el usuario hace clic en el botón Buscar, crearemos una clase anónima Runnable que buscará la palabra escrita en R.id.wordEt EditText e iniciará el subproceso para ejecutar Runnable.

Cuando termine la búsqueda, crearemos una instancia de Runnable SetSynonymResult para publicar el resultado en el sintagma TextView sobre el subproceso de la interfaz de usuario.

Esta técnica es alguna vez no la más conveniente, especialmente cuando no tenemos acceso a una instancia de la actividad; Por lo tanto, en los capítulos siguientes, vamos a discutir técnicas más simples y más limpias para actualizar la interfaz de usuario de una tarea de computación de fondo.

 public class MainActivity extends AppCompatActivity { class SetSynonymResult implements Runnable { String synonym; SetSynonymResult(String synonym) { this.synonym = synonym; } public void run() { Log.d("AsyncAndroid", String.format("Sending synonym result %s on %d", synonym, Thread.currentThread().getId()) + " !"); TextView tv = (TextView) findViewById(R.id.synonymTv); tv.setText(this.synonym); } } ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button search = (Button) findViewById(R.id.searchBut); final EditText word = (EditText) findViewById(R.id.wordEt); search.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Runnable searchTask = new Runnable() { @Override public void run() { String result = searchSynomim(word.getText().toString()); Log.d("AsyncAndroid", String.format("Searching for synonym for %s on %s", word.getText(), Thread.currentThread().getName())); runOnUiThread(new SetSynonymResult(result)); } }; Thread thread = new Thread(searchTask); thread.start(); } }); } static int i = 0; String searchSynomim(String word) { return ++i % 2 == 0 ? "fake" : "mock"; } } 

Fuente :

Asynchronous android programming Helder Vasconcelos

Así es como lo uso:

 runOnUiThread(new Runnable() { @Override public void run() { //Do something on UiThread } }); 

Tu esto

 @UiThread public void logMsg(final String msg) { new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { Log.d("UI thread", "I am the UI thread"); } }); } 
  • IU de Android: ¿cuándo puedo modificar directamente una vista?
  • Servicio de Android e hilo de la interfaz de usuario
  • ¿Qué sucede con un AsyncTask cuando la actividad de lanzamiento se detiene / destruye mientras todavía se está ejecutando?
  • Android, creando un hilo sencillo que actualizará mi contador de segundos
  • Android - SQLite ContentResolver insertar / eliminar / actualizar en UI Thread?
  • ¿Qué es el UiThread de Android (subproceso de interfaz de usuario)
  • No se puede crear el controlador dentro de hilo que no ha llamado Looper.prepare ()
  • Android ViewPager cambia automáticamente la página
  • ¿Es apropiado SQL o acceso general a archivos en el hilo principal de la interfaz de usuario de Android?
  • Android: ¿Posible que el hilo de fondo bloquee hasta que el hilo de UI finalice la operación?
  • Configuración de TextView visible desde otro hilo o BeginInvoke en Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.