No se puede crear el controlador dentro de hilo que no ha llamado Looper.prepare ()

¿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) 

Lo estás llamando desde un hilo de trabajo. Necesita llamar a Toast.makeText() (y la mayoría de las demás funciones que se ocupan de la interfaz de usuario) desde el subproceso principal. Por ejemplo, podrías usar un manejador.

Buscar Comunicación con el subproceso de interfaz de usuario en la documentación. En una palabra:

 // Set this up in the UI thread. mHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message message) { // This is where you do your work in the UI thread. // Your worker tells you in the message what to do. } }; void workerThread() { // And this is how you call it from the worker thread: Message message = mHandler.obtainMessage(command, parameter); message.sendToTarget(); } 

Otras opciones:

Usted podría utilizar un AsyncTask , que funciona bien para la mayoría de las cosas que se ejecutan en el fondo. Tiene ganchos que puede llamar para indicar el progreso, y cuando se hace.

También puede utilizar Activity.runOnUiThread () .

Necesita llamar a Toast.makeText(...) desde el subproceso de la interfaz de usuario:

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

Esto es copia-pegado de otro (duplicado) SO respuesta .

ACTUALIZACIÓN – 2016

La mejor alternativa es usar RxAndroid (enlaces específicos para RxJava ) para que el P en MVP haga cargo de los datos.

Comience por devolver Observable de su método existente.

 private Observable<PojoObject> getObservableItems() { return Observable.create(subscriber -> { for (PojoObject pojoObject: pojoObjects) { subscriber.onNext(pojoObject); } subscriber.onCompleted(); }); } 

Utilice este Observable como este –

 getObservableItems(). subscribeOn(Schedulers.io()). observeOn(AndroidSchedulers.mainThread()). subscribe(new Observer<PojoObject> () { @Override public void onCompleted() { // Print Toast on completion } @Override public void onError(Throwable e) {} @Override public void onNext(PojoObject pojoObject) { // Show Progress } }); } 

————————————————– ————————————————– ——————————

Sé que estoy un poco tarde, pero aquí va. Android básicamente funciona en dos tipos de hilos, a saber, el hilo de la interfaz de usuario y el hilo de fondo . De acuerdo con la documentación de Android –

No tiene acceso al kit de herramientas de la interfaz de usuario de Android desde fuera del hilo de la interfaz de usuario para solucionar este problema, Android ofrece varias formas de acceder al subproceso de interfaz de usuario de 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 ejemplo de código:

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 subproceso. Los hilos por defecto no tienen un bucle de mensaje asociado con ellos; Para crear uno, llame prepare () en el subproceso que va a ejecutar el bucle, y luego loop () para que los mensajes de proceso hasta que el bucle se detiene.

 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 trabajo asincrónico 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 necesidad de que usted mismo maneje subprocesos y / o controladores.

 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 subproceso.

 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; } }); 

Pruebe esto, cuando vea runtimeException debido a Looper no preparado antes del controlador.

 Handler handler = new Handler(Looper.getMainLooper()); handler.postDelayed(new Runnable() { @override void run() { // Run your task here } }, 1000 ); 

Me encontré con el mismo problema, y ​​aquí es cómo lo arreglé:

 private final class UIHandler extends Handler { public static final int DISPLAY_UI_TOAST = 0; public static final int DISPLAY_UI_DIALOG = 1; public UIHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { switch(msg.what) { case UIHandler.DISPLAY_UI_TOAST: { Context context = getApplicationContext(); Toast t = Toast.makeText(context, (String)msg.obj, Toast.LENGTH_LONG); t.show(); } case UIHandler.DISPLAY_UI_DIALOG: //TBD default: break; } } } protected void handleUIRequest(String message) { Message msg = uiHandler.obtainMessage(UIHandler.DISPLAY_UI_TOAST); msg.obj = message; uiHandler.sendMessage(msg); } 

Para crear el UIHandler, necesitará realizar lo siguiente:

  HandlerThread uiThread = new HandlerThread("UIHandler"); uiThread.start(); uiHandler = new UIHandler((HandlerThread) uiThread.getLooper()); 

Espero que esto ayude.

Motivo del error:

Los hilos de trabajo están destinados a realizar tareas de fondo y no se puede mostrar nada en la interfaz de usuario dentro de un subproceso de trabajo a menos que se llame al método runOnUiThread . Si intenta mostrar algo en el subproceso de UI sin llamar a runOnUiThread, habrá un java.lang.RuntimeException .

Por lo tanto, si está en una activity pero llama a Toast.makeText() desde el subproceso de trabajo, haga lo siguiente:

 runOnUiThread(new Runnable() { public void run() { Toast toast = Toast.makeText(getApplicationContext(), "Something", Toast.LENGTH_SHORT).show(); } }); 

El código anterior asegura que está mostrando el mensaje Toast en un UI thread ya que lo está llamando dentro del método runOnUiThread . Así que no más java.lang.RuntimeException .

Estaba recibiendo este error hasta que hice lo siguiente.

 public void somethingHappened(final Context context) { Handler handler = new Handler(Looper.getMainLooper()); handler.post( new Runnable() { @Override public void run() { Toast.makeText(context, "Something happened.", Toast.LENGTH_SHORT).show(); } } ); } 

Y convirtió esto en una clase singleton:

 public enum Toaster { INSTANCE; private final Handler handler = new Handler(Looper.getMainLooper()); public void postMessage(final String message) { handler.post( new Runnable() { @Override public void run() { Toast.makeText(ApplicationHolder.INSTANCE.getCustomApplication(), message, Toast.LENGTH_SHORT) .show(); } } ); } } 

eso fue lo que hice.

 new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { Toast(...); } }); 

Los componentes visuales están "bloqueados" a los cambios de los hilos externos. Por lo tanto, dado que el brindis muestra cosas en la pantalla principal que es administrada por el hilo principal, es necesario ejecutar este código en ese hilo. Espero que ayude:)

Una ventaja de este método es que se puede utilizar en clases que no sean de actividad también:

 new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { Toast toast = Toast.makeText(mContext, "Something", Toast.LENGTH_SHORT); } }); 

La respuesta de ChicoBird funcionó para mí. El único cambio que hice fue en la creación del UIHandler donde tenía que hacer

 HandlerThread uiThread = new HandlerThread("UIHandler"); 

Eclipse se negó a aceptar cualquier otra cosa. Tiene sentido supongo.

También el uiHandler es claramente una clase global definida en alguna parte. Sigo sin pretender entender cómo Android está haciendo esto y lo que está pasando, pero me alegro de que funcione. Ahora voy a proceder a estudiarlo y ver si puedo entender lo que está haciendo Android y por qué uno tiene que pasar por todos estos aros y bucles. Gracias por la ayuda ChicoBird.

Esto es porque Toast.makeText () está llamando desde un subproceso de trabajo. Debe ser llamada desde el hilo principal de la interfaz de usuario como este

 runOnUiThread(new Runnable() { public void run() { Toast toast = Toast.makeText(mContext, "Something", Toast.LENGTH_SHORT); } }); 

Estaba funcionando en el mismo problema cuando mis devoluciones de llamada intentarían demostrar un diálogo.

Lo solucioné con métodos dedicados en la actividad – en el nivel de miembro de instancia de Activity – que utilizan runOnUiThread(..)

 public void showAuthProgressDialog() { runOnUiThread(new Runnable() { @Override public void run() { mAuthProgressDialog = DialogUtil.getVisibleProgressDialog(SignInActivity.this, "Loading ..."); } }); } public void dismissAuthProgressDialog() { runOnUiThread(new Runnable() { @Override public void run() { if (mAuthProgressDialog == null || ! mAuthProgressDialog.isShowing()) { return; } mAuthProgressDialog.dismiss(); } }); } 

Para Rxjava y RxAndroid Usuario:

 public static void shortToast(String msg) { Observable.just(msg) .observeOn(AndroidSchedulers.mainThread()) .subscribe(message -> { Toast.makeText(App.getInstance(), message, Toast.LENGTH_SHORT).show(); }); } 

Toast, AlertDialogs necesita ejecutarse en el hilo de interfaz de usuario, puede utilizar Asynctask para usarlos correctamente en android development.but algunos casos tenemos que personalizar los tiempos de espera, por lo que usamos Threads , pero en los hilos no podemos usar Toast, Alertdialogs como we using En AsyncTask.So necesitamos manejador separado para popup los.

 public void onSigned() { Thread thread = new Thread(){ @Override public void run() { try{ sleep(3000); Message message = new Message(); message.what = 2; handler.sendMessage(message); } catch (Exception e){ e.printStackTrace(); } } }; thread.start(); } 

En el ejemplo de arriba quiero dormir mi hilo en 3sec y después quiero mostrar un mensaje de Toast, para eso en su mainthread implementar manejador.

 handler = new Handler() { public void handleMessage(Message msg) { switch(msg.what){ case 1: Toast.makeText(getActivity(),"cool",Toast.LENGTH_SHORT).show(); break; } super.handleMessage(msg); } }; 

Utilicé el caso del interruptor aquí, porque si usted necesita mostrar el mensaje diferente de la misma manera, usted puede utilizar la caja del interruptor dentro de la clase del manejo … espere que esto le ayudará

Para mostrar un diálogo o una tostadora en un subproceso, la forma más concisa es utilizar el objeto Activity.

Por ejemplo:

 new Thread(new Runnable() { @Override public void run() { myActivity.runOnUiThread(new Runnable() { public void run() { myActivity.this.processingWaitDialog = new ProgressDialog(myActivity.this.getContext()); myActivity.this.processingWaitDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); myActivity.this.processingWaitDialog.setMessage("abc"); myActivity.this.processingWaitDialog.setIndeterminate(true); myActivity.this.processingWaitDialog.show(); } }); expenseClassify.serverPost( new AsyncOperationCallback() { public void operationCompleted(Object sender) { myActivity.runOnUiThread(new Runnable() { public void run() { if (myActivity.this.processingWaitDialog != null && myActivity.this.processingWaitDialog.isShowing()) { myActivity.this.processingWaitDialog.dismiss(); myActivity.this.processingWaitDialog = null; } } }); // .runOnUiThread(new Runnable() ... 
  • Android - SQLite ContentResolver insertar / eliminar / actualizar en UI Thread?
  • ¿Es posible usar AsyncTask en una clase de servicio?
  • ¿OnPreExecute () y onPostExecute () se ejecutan en el subproceso de interfaz de usuario o en el subproceso desde el que se inició AsyncTask?
  • Servicio de Android e hilo de la interfaz de usuario
  • No se puede crear el controlador dentro de hilo que no ha llamado Looper.prepare () 3
  • Cómo saber si este hilo es un hilo de interfaz de usuario
  • No se muestra la vista de Android después del método addView
  • Android - llamando al hilo de ui del hilo de trabajo
  • ¿Qué es el UiThread de Android (subproceso de interfaz de usuario)
  • Cómo actualizar la interfaz de usuario desde el servicio de Android utilizando RxJava / RxAndroid
  • ¿Cómo ejecutar algún código en el asíncrono de la interfaz de usuario de Android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.