android - java.lang.RuntimeException: No se puede crear el controlador dentro de la cadena que no ha llamado a Looper.prepare();
multithreading toast (5)
Tengo una aplicación de Android con un hilo. Quiero que se muestre un mensaje de Toast con un mensaje.
Cuando hago esto, obtengo la siguiente excepción:
Traza de Logcat :
FATAL EXCEPTION: Timer-0
java.lang.RuntimeException: Can''t create handler inside thread that has not
called Looper.prepare()
at android.os.Handler.<init>(Handler.java:121)
at android.widget.Toast$TN.<init>(Toast.java:322)
at android.widget.Toast.<init>(Toast.java:91)
at android.widget.Toast.makeText(Toast.java:238)
¿Existe una solución alternativa para enviar mensajes de Toast desde hilos a la interfaz de usuario?
Android básicamente funciona en dos tipos de subprocesos, a saber, subproceso de interfaz de usuario e hilo de fondo. De acuerdo con la documentación de Android -
No acceda al kit de herramientas de la interfaz de usuario de Android desde fuera del subproceso de la interfaz de usuario para solucionar este problema. Android ofrece varias formas de acceder al subproceso de la interfaz de usuario desde otros subprocesos. Aquí hay una lista de métodos que pueden ayudar:
Activity.runOnUiThread(Runnable)
View.post(Runnable)
View.postDelayed(Runnable, long)
Ahora hay varios métodos para resolver este problema. Lo explicaré por código de muestra
runOnUiThread
new Thread()
{
public void run()
{
myactivity.this.runOnUiThread(new runnable()
{
public void run()
{
//Do your UI operations like dialog opening or Toast here
}
});
}
}.start();
LOOPER
Clase utilizada para ejecutar un bucle de mensaje para un hilo. Los hilos por defecto no tienen un bucle de mensaje asociado a ellos; para crear uno, llame a prepare () en el hilo que ejecutará el ciclo, y luego a loop () para que procese los mensajes hasta que se detenga el ciclo.
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
AsyncTask
AsyncTask le permite realizar trabajos asincrónicos en su interfaz de usuario. Realiza las operaciones de bloqueo en un subproceso de trabajo y luego publica los resultados en el subproceso de interfaz de usuario, sin que sea necesario que maneje los subprocesos y / o controladores usted mismo.
public void onClick(View v) {
new CustomTask().execute((Void[])null);
}
private class CustomTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... param) {
//Do some work
return null;
}
protected void onPostExecute(Void param) {
//Print Toast or open dialog
}
}
Entrenador de animales
Un controlador le permite enviar y procesar mensajes y objetos ejecutables asociados con MessageQueue de un hilo.
Message msg = new Message();
new Thread()
{
public void run()
{
msg.arg1=1;
handler.sendMessage(msg);
}
}.start();
Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
if(msg.arg1==1)
{
//Print Toast or open dialog
}
return false;
}
});
Desde http://developer.android.com/guide/components/processes-and-threads.html :
Además, el toolkit Android UI no es seguro para subprocesos. Por lo tanto, no debe manipular su UI a partir de un hilo de trabajo: debe hacer toda la manipulación a su interfaz de usuario desde el hilo de UI. Por lo tanto, simplemente hay dos reglas para el modelo de un solo hilo de Android:
- No bloquee el hilo de UI
- No acceda al juego de herramientas de interfaz de usuario de Android desde fuera del hilo de la interfaz de usuario
Debe detectar la inactividad en un hilo de trabajo y mostrar un brindis en el hilo principal.
Por favor, publique un código, si quiere una respuesta más detallada.
Después de la publicación del código:
En strings.xml
<string name="idleness_toast">"You are getting late do it fast"</string>
En YourWorkerThread.java
Toast.makeText(getApplicationContext(), getString(R.string.idleness_toast),
Toast.LENGTH_LONG).show();
No use AlertDialog, haga una elección. AlertDialog y Toast son dos cosas diferentes.
Esto es lo que he estado haciendo:
public void displayError(final String errorText) {
Runnable doDisplayError = new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), errorText, Toast.LENGTH_LONG).show();
}
};
messageHandler.post(doDisplayError);
}
Eso debería permitir que el método sea llamado desde cualquiera de los hilos.
Donde messageHandler se declara en la actividad como ...
Handler messageHandler = new Handler();
Obtuve esta excepción porque estaba tratando de hacer una ventana emergente Toast de un hilo de fondo.
Toast necesita una actividad para enviar a la interfaz de usuario y los hilos no la tienen.
Entonces, una solución alternativa es darle al hilo un enlace a la actividad principal y brindar por eso.
Coloque este código en el hilo donde desea enviar un mensaje de Toast:
parent.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(parent.getBaseContext(), "Hello", Toast.LENGTH_LONG).show();
}
});
Mantenga un enlace a la Actividad principal en el hilo de fondo que creó este hilo. Use la variable padre en su clase de subprocesos:
private static YourActivity parent;
Cuando creas el hilo, pasa la Actividad padre como un parámetro a través del constructor de esta manera:
public YourBackgroundThread(YourActivity parent) {
this.parent = parent;
}
Ahora el hilo de fondo puede enviar mensajes de Toast a la pantalla.
Simplemente puede usar BeginInvokeOnMainThread (). Invoca una Acción en el hilo principal del dispositivo (UI).
Device.BeginInvokeOnMainThread(() => { displayToast("text to display"); });
¡Es simple y funciona perfectamente para mí!
EDITAR: Funciona si estás usando C # Xamarin