78 votes

Impossible de créer un gestionnaire dans un thread qui n'a pas appelé Looper.prepare() dans une tâche asynchrone pour ProgressDialog.

Je ne comprends pas pourquoi je reçois cette erreur. J'utilise AsyncTask pour exécuter certains processus en arrière-plan.

Je l'ai fait :

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

Quand je suis dans doInBackground() en fonction d'une condition I :

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

Chaque fois que j'essaie downloadSpinnerProgressDialog.show() Je reçois l'erreur.

Des idées ?

105voto

Konstantin Burov Points 34011

La méthode show() doit être appelé à partir du Fil conducteur de l'interface utilisateur (IU) alors que doInBackground() fonctionne sur un fil différent, ce qui est la raison principale pour laquelle AsyncTask a été conçu.

Vous devez appeler show() soit dans onProgressUpdate() ou dans onPostExecute() .

Par exemple :

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

81voto

hyui Points 521

J'ai eu un problème similaire, mais en lisant cette question, j'ai compris que je pouvais fonctionner sur un thread UI :

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

Ça semble faire l'affaire pour moi.

1voto

caiocpricci2 Points 3681

J'ai eu du mal à faire fonctionner cela aussi, la solution pour moi était d'utiliser les réponses de hyui et de 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();
       }
     });
 }

}

0voto

jayesh kavathiya Points 1346
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();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X