Android: brindis en un hilo

¿Cómo puedo mostrar los mensajes de Toast de un hilo?

Puedes hacerlo llamando al método runOnUiThread una Activity desde tu hilo:

 activity.runOnUiThread(new Runnable() { public void run() { Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show(); } }); 

Me gusta tener un método en mi actividad llamado showToast que pueda llamar desde cualquier lugar …

 public void showToast(final String toast) { runOnUiThread(() -> Toast.makeText(MyActivity.this, toast, Toast.LENGTH_SHORT).show()); } 

Entonces, con más frecuencia lo llamo desde MyActivity en cualquier hilo como este …

 showToast(getString(R.string.MyMessage)); 

Esto es similar a otras respuestas, sin embargo actualizado para las nuevas aplicaciones disponibles y mucho más limpio. Además, no asume que estás en un contexto de actividad.

 public class MyService extends AnyContextSubclass { public void postToastMessage(final String message) { Handler handler = new Handler(Looper.getMainLooper()); handler.post(new Runnable() { @Override public void run() { Toast.makeText(getContext(), message, Toast.LENGTH_LONG).show(); } }); } } 

Me gusta esto o esto , con un Runnable que muestra el Toast . A saber,

 Activity activity = // reference to an Activity // or View view = // reference to a View activity.runOnUiThread(new Runnable() { @Override public void run() { showToast(activity); } }); // or view.post(new Runnable() { @Override public void run() { showToast(view.getContext()); } }); private void showToast(Context ctx) { Toast.makeText(ctx, "Hi!", Toast.LENGTH_SHORT).show(); } 

En ocasiones, debe enviar un mensaje de otro Thread al Thread de interfaz de usuario. Este tipo de escenario ocurre cuando no puede ejecutar las operaciones de red / IO en el hilo de la interfaz de usuario.

El ejemplo siguiente maneja ese escenario.

  1. Usted tiene un hilo UI
  2. Runnable iniciar la operación IO y, por lo tanto, no puede ejecutar Runnable en el hilo de UI. Runnable tu Runnable en handler en HandlerThread
  3. Obtenga el resultado de Runnable y envíelo de nuevo al hilo de la interfaz de usuario y muestre un mensaje de Toast .

Solución:

  1. Crea un HandlerThread y comienza
  2. Crear un HandlerThread con Looper desde HandlerThread : requestHandler
  3. Cree un controlador con Looper desde Main Thread: responseHandler y anule el método handleMessage
  4. post una tarea requestHandler en requestHandler
  5. Dentro de la tarea Runnable , llame a sendMessage en responseHandler
  6. Esta sendMessage resultado sendMessage de handleMessage en responseHandler .
  7. Obtener atributos del Message y procesarlo, actualizar la interfaz de usuario

Código de muestra:

  /* Handler thread */ HandlerThread handlerThread = new HandlerThread("HandlerThread"); handlerThread.start(); Handler requestHandler = new Handler(handlerThread.getLooper()); final Handler responseHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { //txtView.setText((String) msg.obj); Toast.makeText(MainActivity.this, "Runnable on HandlerThread is completed and got result:"+(String)msg.obj, Toast.LENGTH_LONG) .show(); } }; for ( int i=0; i<5; i++) { Runnable myRunnable = new Runnable() { @Override public void run() { try { /* Add your business logic here and construct the Messgae which should be handled in UI thread. For example sake, just sending a simple Text here*/ String text = "" + (++rId); Message msg = new Message(); msg.obj = text.toString(); responseHandler.sendMessage(msg); System.out.println(text.toString()); } catch (Exception err) { err.printStackTrace(); } } }; requestHandler.post(myRunnable); } 

Artículos útiles:

handlerthreads-and-why-you-be-be-usand-them-in-your-android-apps

android-looper-handler-handlerthread-i

Un enfoque que funciona desde casi cualquier lugar, incluso desde lugares donde no tiene una Activity o View , es agarrar un Handler al hilo principal y mostrar el brindis:

 public void toast(final Context context, final String text) { Handler handler = new Handler(Looper.getMainLooper()); handler.post(new Runnable() { public void run() { Toast.makeText(context, text, Toast.DURATION_LONG).show(); } }); } 

La ventaja de este enfoque es que funciona con cualquier Context , incluido el Service y la Application .

  1. Obtenga la instancia de UI Thread Handler y use handler.sendMessage();
  2. Call post() método handler.post();
  3. runOnUiThread()
  4. view.post()

Puede usar Looper para enviar un mensaje de Toast . Visita este enlace para más detalles.

 public void showToastInThread(final Context context,final String str){ Looper.prepare(); MessageQueue queue = Looper.myQueue(); queue.addIdleHandler(new IdleHandler() { int mReqCount = 0; @Override public boolean queueIdle() { if (++mReqCount == 2) { Looper.myLooper().quit(); return false; } else return true; } }); Toast.makeText(context, str,Toast.LENGTH_LONG).show(); Looper.loop(); } 

y es llamado en tu hilo. El contexto puede ser Activity.getContext() obteniendo de la Activity que tiene que mostrar el brindis.

Hice este enfoque basado en la respuesta mjaggard:

 public static void toastAnywhere(final String text) { Handler handler = new Handler(Looper.getMainLooper()); handler.post(new Runnable() { public void run() { Toast.makeText(SuperApplication.getInstance().getApplicationContext(), text, Toast.LENGTH_LONG).show(); } }); } 

Funcionó bien para mí

Me encontré con el mismo problema:

 E/AndroidRuntime: FATAL EXCEPTION: Thread-4 Process: com.example.languoguang.welcomeapp, PID: 4724 java.lang.RuntimeException: Can't toast on a thread that has not called Looper.prepare() at android.widget.Toast$TN.(Toast.java:393) at android.widget.Toast.(Toast.java:117) at android.widget.Toast.makeText(Toast.java:280) at android.widget.Toast.makeText(Toast.java:270) at com.example.languoguang.welcomeapp.MainActivity$1.run(MainActivity.java:51) at java.lang.Thread.run(Thread.java:764) I/Process: Sending signal. PID: 4724 SIG: 9 Application terminated. 

Antes: función onCreate

 Thread thread = new Thread(new Runnable() { @Override public void run() { Toast.makeText(getBaseContext(), "Thread", Toast.LENGTH_LONG).show(); } }); thread.start(); 

Después: función onCreate

 runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getBaseContext(), "Thread", Toast.LENGTH_LONG).show(); } }); 

funcionó.