thread - Android: brindis en un hilo
threadpool android (10)
- Obtenga la instancia de UI Thread Handler y use
handler.sendMessage(); - Call
post()métodohandler.post(); -
runOnUiThread() -
view.post()
¿Cómo puedo mostrar los mensajes de Toast de un hilo?
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.
- Usted tiene un hilo UI
-
Runnableiniciar la operación IO y, por lo tanto, no puede ejecutarRunnableen el hilo de UI.RunnabletuRunnableen handler enHandlerThread - Obtenga el resultado de
Runnabley envíelo de nuevo al hilo de la interfaz de usuario y muestre un mensaje deToast.
Solución:
- Crea un HandlerThread y comienza
- Crear un
HandlerThreadcon Looper desdeHandlerThread:requestHandler - Cree un controlador con Looper desde Main Thread:
responseHandlery anule el métodohandleMessage -
postuna tarearequestHandlerenrequestHandler - Dentro de la tarea
Runnable, llame asendMessageenresponseHandler - Esta
sendMessageresultadosendMessagedehandleMessageenresponseHandler. - Obtener atributos del
Messagey 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-should-be-using-them-in-your-android-apps
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();
}
});
}
}
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.<init>(Toast.java:393)
at android.widget.Toast.<init>(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ó.
Me gusta this o this , 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();
}
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));
Puede usar Looper para enviar un mensaje de Toast . Visita este link 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.
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 .
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();
}
});