Pregunta No se puede crear el controlador dentro de la cadena que no ha llamado a Looper.prepare ()


Tengo una actividad, y en eso tengo una clase.

text=new Dynamictext(...);
text.setText("txt");

en mi DynamicText java tengo este código:

public void setText(String text) {
    this.text=text;
    new asyncCreateText().execute();
    //this.createText(text);
}

//private Handler handler = new Handler();

private class asyncCreateText extends AsyncTask<Void, Void, Void> 
{
    @Override
    protected Void doInBackground(Void... unused) {
        return null;
    }

    @Override
    protected void onPostExecute(Void unused) {

    }
}

Yo obtengo:

ERROR / AndroidRuntime (5176): Causado por: java.lang.RuntimeException: No se puede crear el controlador en el subproceso que no ha llamado a Looper.prepare ()

¿Cómo puedo manejar este error?

ERROR/AndroidRuntime(5370): java.lang.ExceptionInInitializerError
ERROR/AndroidRuntime(5370):     at com.l.start.DynamicText.setText(DynamicText.java:125)
ERROR/AndroidRuntime(5370):     at com.l.start.OpenGLRenderer.initfonts(OpenGLRenderer.java:168)
ERROR/AndroidRuntime(5370):     at com.l.start.OpenGLRenderer.init(OpenGLRenderer.java:119)
ERROR/AndroidRuntime(5370):     at com.l.start.OpenGLRenderer.onSurfaceChanged(OpenGLRenderer.java:90)
ERROR/AndroidRuntime(5370):     at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1120)
ERROR/AndroidRuntime(5370):     at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:975)

ERROR/AndroidRuntime(5370): Caused by: java.lang.RuntimeException: 
    Can't create handler inside thread that has not called Looper.prepare()
ERROR/AndroidRuntime(5370):     at android.os.Handler.<init>(Handler.java:121)
ERROR/AndroidRuntime(5370):     at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
ERROR/AndroidRuntime(5370):     at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
ERROR/AndroidRuntime(5370):     at android.os.AsyncTask.<clinit>(AsyncTask.java:152)
ERROR/AndroidRuntime(5370):     ... 6 more

74
2018-02-15 21:36


origen


Respuestas:


El error es autoexplicativo ... doInBackground() se ejecuta en un hilo de fondo que, dado que no está destinado a bucle, no está conectado a un Looper.

Lo más probable es que no desee crear una instancia directa de un controlador ... cualquiera que sea su información doInBackground() los retornos de implementación se pasarán a onPostExecute() que se ejecuta en el hilo de UI.

   mActivity = ThisActivity.this; 

    mActivity.runOnUiThread(new Runnable() {
     public void run() {
     new asyncCreateText().execute();
     }
   });

AGREGADO SIGUIENDO EL STACKTRACE QUE APARECE EN LA PREGUNTA:

Parece que estás tratando de comenzar un AsyncTask desde un hilo de renderizado GL ... no hagas eso porque nunca lo harán Looper.loop() ya sea. AsyncTasks están realmente diseñados para ejecutarse solo desde el hilo de la interfaz de usuario.

La solución menos disruptiva sería probablemente llamar Activity.runOnUiThread() con un Runnable eso inicia tu AsyncTask.


143
2018-02-15 21:43



Todas las respuestas anteriores son correctas, pero creo que este es el ejemplo más fácil posible:

public class ExampleActivity extends Activity {
    private Handler handler;
    private ProgressBar progress;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        progress = (ProgressBar) findViewById(R.id.progressBar1);
        handler = new Handler();
    }

    public void clickAButton(View view) {
        // Do something that takes a while
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                handler.post(new Runnable() { // This thread runs in the UI
                    @Override
                    public void run() {
                        progress.setProgress("anything"); // Update the UI
                    }
                });
            }
        };
        new Thread(runnable).start();
    }
}

Lo que hace esto es actualizar una barra de progreso en el hilo de la interfaz de usuario desde un hilo completamente diferente pasado a través del método post () del controlador declarado en la actividad.

¡Espero eso ayude!


28
2018-04-05 16:00



Crea el controlador en el hilo de fondo de esta manera

private void createHandler() {
        Thread thread = new Thread() {
          public void run() {
               Looper.prepare();

               final Handler handler = new Handler();
               handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                       // Do Work
                        handler.removeCallbacks(this);
                        Looper.myLooper().quit();
                   }
                }, 2000);

                Looper.loop();
            }
        };
        thread.start();
    }

19
2017-12-22 09:36



Activity.runOnUiThread() no funciona para mi Trabajé alrededor de este problema creando un hilo regular de esta manera:

public class PullTasksThread extends Thread {
   public void run () {
      Log.d(Prefs.TAG, "Thread run...");
   }
}

y llamándolo desde la actualización GL de esta manera:

new PullTasksThread().start();

11
2017-08-01 08:40



Intenta ejecutarte asyntask desde el hilo de UI. ¡Me enfrenté a este problema cuando no estaba haciendo lo mismo!


4
2017-07-08 09:18



Prueba esto

    Handler mHandler = new Handler(Looper.getMainLooper());
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
 //your code here that talks with the UI level widgets/ try to access the UI 
//elements from this block because this piece of snippet will run in the UI/MainThread.                                     
                            }
                        });

2
2018-02-13 14:51