¿Qué significa la siguiente excepción? ¿Cómo puedo arreglarlo?
Este es el código:
Toast toast = Toast.makeText(mContext, "Something", Toast.LENGTH_SHORT);
Esta es la excepción:
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.<init>(Toast.java:68)
at android.widget.Toast.makeText(Toast.java:231)
android
ui-thread
android-toast
Miguel
fuente
fuente
compile 'com.shamanland:xdroid-toaster:0.0.5'
, no requiererunOnUiThread()
oContext
variable, ¡toda la rutina se ha ido! solo invoqueToaster.toast(R.string.my_msg);
aquí es el ejemplo: github.com/shamanland/xdroid-toaster-exampleRespuestas:
Lo estás llamando desde un hilo de trabajo. Debe llamar
Toast.makeText()
(y la mayoría de las otras funciones relacionadas con la IU) desde el hilo principal. Podría usar un controlador, por ejemplo.Consulte Comunicación con el subproceso de interfaz de usuario en la documentación. En una palabra:
Otras opciones:
Puede usar una AsyncTask , que funciona bien para la mayoría de las cosas que se ejecutan en segundo plano. Tiene ganchos a los que puede llamar para indicar el progreso y cuándo está hecho.
También puede usar Activity.runOnUiThread () .
fuente
(and most other functions dealing with the UI)
Un ejemplo de una función de interfaz de usuario que se puede usar desde el fondo esandroid.support.design.widget.Snackbar
: su funcionalidad no se ve mermada cuando no se llama desde el hilo de la interfaz de usuario.Debe llamar
Toast.makeText(...)
desde el hilo de la interfaz de usuario:Esto se copia de otra respuesta SO (duplicada) .
fuente
ACTUALIZACIÓN - 2016
La mejor alternativa es utilizar
RxAndroid
(fijaciones específicas paraRxJava
) para elP
deMVP
hacerse cargo fo datos.Comience por regresar
Observable
de su método existente.Use este Observable como este:
-------------------------------------------------- -------------------------------------------------- ------------------------------
Sé que llego un poco tarde pero aquí va. Básicamente, Android funciona en dos tipos de subprocesos, a saber, subproceso de interfaz de usuario y subproceso de fondo . De acuerdo con la documentación de Android:
Ahora hay varios métodos para resolver este problema.
Lo explicaré por ejemplo de código:
runOnUiThread
LOOPER
AsyncTask
Manipulador
fuente
runOnUiThread
View
también tiene métodospost(Runnable)
ypostDelayed(Runnable, long)
! Tantos manipuladores en vano. :)Toast.makeText()
solo debe llamarse desde el subproceso principal / UI. Looper.getMainLooper () te ayuda a lograrlo:Una ventaja de este método es que puede usarlo sin Actividad o Contexto.
fuente
Intente esto, cuando vea runtimeException debido a que Looper no está preparado antes del controlador.
fuente
android.os.Handler
Me encontré con el mismo problema, y así es como lo solucioné:
Para crear el UIHandler, deberá realizar lo siguiente:
Espero que esto ayude.
fuente
onCreate method
o desde AsyncTask en mi situación, ¿podría publicar todo el código solo para saber cómo funcionan las cosas?uiHandler = new UIHandler(uiThread.getLooper());
?Motivo de un error:
Los subprocesos de trabajo están destinados a realizar tareas en segundo plano y no puede mostrar nada en la interfaz de usuario dentro de un subproceso de trabajo a menos que llame a un método como runOnUiThread . Si intenta mostrar algo en el hilo de la interfaz de usuario sin llamar a runOnUiThread, habrá un
java.lang.RuntimeException
.Entonces, si está en un hilo de trabajador
activity
pero llamandoToast.makeText()
, haga esto:El código anterior asegura que está mostrando el mensaje Toast en un método
UI thread
ya que lo está llamando dentrorunOnUiThread
. Entonces no másjava.lang.RuntimeException
.fuente
eso fue lo que hice.
Los componentes visuales están "bloqueados" a los cambios desde hilos externos. Entonces, dado que el brindis muestra cosas en la pantalla principal administradas por el hilo principal, debe ejecutar este código en ese hilo. Espero que ayude:)
fuente
Recibí este error hasta que hice lo siguiente.
Y convirtió esto en una clase singleton:
fuente
Toaster.INSTANCE.postMessage(ResourceUtils.getString(R.string.blah));
(¡lo sé, lo reducimos más tarde!), aunque no he estado usando tostadas en mucho tiempoApplicationHolder.INSTANCE
evalúa?CustomApplication
CustomApplication.onCreate()
fuente
runOnUiThread(() -> { Toast toast = Toast.makeText(getApplicationContext(), "Message", Toast.LENGTH_SHORT); toast.show(); });
Maravillosa solución de Kotlin:
fuente
runOnUiThread
es parte de la actividad, es deciractivity?.runOnUiThread { ... }
Esto se debe a que Toast.makeText () está llamando desde un subproceso de trabajo. Debe llamarse desde el hilo principal de la interfaz de usuario como este
fuente
La respuesta de ChicoBird funcionó para mí. El único cambio que hice fue en la creación del UIHandler donde tuve que hacer
Eclipse se negó a aceptar cualquier otra cosa. Tiene sentido, supongo.
Además,
uiHandler
es claramente una clase global definida en alguna parte. Todavía no pretendo entender cómo Android está haciendo esto y qué está sucediendo, pero me alegro de que funcione. Ahora procederé a estudiarlo y veré si puedo entender qué está haciendo Android y por qué uno tiene que pasar por todos estos aros y bucles. Gracias por la ayuda ChicoBird.fuente
primera llamada
Looper.prepare()
y luego llamadaToast.makeText().show()
última llamadaLooper.loop()
como:fuente
Para usuarios de Rxjava y RxAndroid:
fuente
Me encontraba con el mismo problema cuando mis devoluciones de llamada intentaban mostrar un diálogo.
Lo resolví con métodos dedicados en la Actividad, en el nivel de miembro de la instancia de Actividad , que usan
runOnUiThread(..)
fuente
Ahora handler2 usará un hilo diferente para manejar los mensajes que el hilo principal.
fuente
Para mostrar un cuadro de diálogo o una tostadora en un hilo, la forma más concisa es usar el objeto Actividad.
Por ejemplo:
fuente
Toast, AlertDialogs necesita ejecutarse en el hilo de la interfaz de usuario, puede usar Asynctask para usarlos correctamente en el desarrollo de Android. Pero en algunos casos necesitamos personalizar los tiempos de espera, por lo que usamos hilos , pero en los hilos no podemos usar Toast, Alertdialogs como usamos en AsyncTask.So que necesita separar Handler para aquellos emergente.
en el ejemplo anterior, quiero dormir mi hilo en 3 segundos y después quiero mostrar un mensaje Toast, para eso en su controlador de implementación de hilo principal .
Usé el caso de cambio aquí, porque si necesita mostrar un mensaje diferente de la misma manera, puede usar el caso de cambio dentro de la clase Handler ... espero que esto lo ayude
fuente
Esto generalmente ocurre cuando se llama a algo en el hilo principal desde cualquier hilo de fondo. Veamos un ejemplo, por ejemplo.
En el ejemplo anterior, estamos configurando texto en la vista de texto que se encuentra en el hilo principal de la interfaz de usuario del método doInBackground (), que opera solo en un hilo de trabajo.
fuente
Tuve el mismo problema y lo solucioné simplemente poniendo Toast en la función de anulación onPostExecute () de Asynctask <> y funcionó.
fuente
uso el siguiente código para mostrar el mensaje del "contexto" del hilo principal,
luego use como lo siguiente:
fuente