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
-
Runnable
iniciar la operación IO y, por lo tanto, no puede ejecutarRunnable
en el hilo de UI.Runnable
tuRunnable
en handler enHandlerThread
- Obtenga el resultado de
Runnable
y 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
HandlerThread
con Looper desdeHandlerThread
:requestHandler
- Cree un controlador con Looper desde Main Thread:
responseHandler
y anule el métodohandleMessage
-
post
una tarearequestHandler
enrequestHandler
- Dentro de la tarea
Runnable
, llame asendMessage
enresponseHandler
- Esta
sendMessage
resultadosendMessage
dehandleMessage
enresponseHandler
. - 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-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();
}
});