No se puede crear un controlador dentro del hilo que no ha llamado a Looper.prepare () dentro de AsyncTask para ProgressDialog

78

No entiendo por qué recibo este error. Estoy usando AsyncTask para ejecutar algunos procesos en segundo plano.

Yo tengo:

protected void onPreExecute() 
{
    connectionProgressDialog = new ProgressDialog(SetPreference.this);
    connectionProgressDialog.setCancelable(true);
    connectionProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    connectionProgressDialog.setMessage("Connecting to site...");
    connectionProgressDialog.show();

    downloadSpinnerProgressDialog = new ProgressDialog(SetPreference.this);
    downloadSpinnerProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    downloadSpinnerProgressDialog.setMessage("Downloading wallpaper...");
}

Cuando entro doInBackground()dependiendo de una condición, yo:

[...]    
connectionProgressDialog.dismiss();
downloadSpinnerProgressDialog.show();
[...]

Siempre que lo intento downloadSpinnerProgressDialog.show(), recibo el error.

¿Alguna idea chicos?

mlevit
fuente

Respuestas:

106

El método show()debe llamarse desde el hilo de la interfaz de usuario (UI) , mientras que se doInBackground()ejecuta en un hilo diferente, que es la razón principal por la que AsyncTaskse diseñó.

Tienes que llamar show(), ya sea en onProgressUpdate()o en onPostExecute().

Por ejemplo:

class ExampleTask extends AsyncTask<String, String, String> {

    // Your onPreExecute method.

    @Override
    protected String doInBackground(String... params) {
        // Your code.
        if (condition_is_true) {
            this.publishProgress("Show the dialog");
        }
        return "Result";
    }

    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);
        connectionProgressDialog.dismiss();
        downloadSpinnerProgressDialog.show();
    }
}
Konstantin Burov
fuente
3
Eso no funcionó para mí, solo probé "AlertDialog.Builder builder = new AlertDialog.Builder (context);" y agregó la configuración del constructor. Intentar mostrar esto dentro de onProgressUpdate conduce exactamente al mismo error. Algunas ideas ?
ins0m
Gracias Konstantin, no me di cuenta de que podía anular onProgressUpdate con cualquier tipo de variable usando publishProgress (). Realmente me ayudó, simplemente actualizar con mensajes tostados.
Wired00
81

Tuve un problema similar, pero al leer esta pregunta pensé que podría ejecutar el hilo de la interfaz de usuario:

YourActivity.this.runOnUiThread(new Runnable() {
    public void run() {
        alertDialog.show();
    }
});

Parece que me sirve.

hyui
fuente
getActivity (). runOnUiThread (this :: mymethod); Gracias funcionó muy bien.
mortezahosseini
1

También me costó mucho hacer que esto funcionara, la solución para mí fue usar las respuestas hyui y konstantin,

class ExampleTask extends AsyncTask<String, String, String> {

// Your onPreExecute method.

@Override
protected String doInBackground(String... params) {
    // Your code.
    if (condition_is_true) {
        this.publishProgress("Show the dialog");
    }
    return "Result";
}

@Override
protected void onProgressUpdate(String... values) {

    super.onProgressUpdate(values);
    YourActivity.this.runOnUiThread(new Runnable() {
       public void run() {
           alertDialog.show();
       }
     });
 }

}
caiocpricci2
fuente
Pensé que las cosas hechas en onProgressUpdate()se ejecutarían automáticamente en el hilo de la interfaz de usuario
alguien en algún lugar
0
final Handler handler = new Handler() {
        @Override
        public void handleMessage(final Message msgs) {
        //write your code hear which give error
        }
        }

new Thread(new Runnable() {
    @Override
    public void run() {
    handler.sendEmptyMessage(1);
        //this will call handleMessage function and hendal all error
    }
    }).start();
Jayesh Kavathiya
fuente