In AsyncTask for ProgressDialog kann kein Handler innerhalb eines Threads erstellt werden, der Looper.prepare () nicht aufgerufen hat

78

Ich verstehe nicht, warum ich diesen Fehler erhalte. Ich verwende AsyncTask, um einige Prozesse im Hintergrund auszuführen.

Ich habe:

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

Wenn ich in doInBackground()Abhängigkeit von einer Bedingung gerate, die ich:

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

Immer wenn ich es versuche, downloadSpinnerProgressDialog.show()erhalte ich den Fehler.

Irgendwelche Ideen Jungs?

mlevit
quelle

Antworten:

106

Die Methode show()muss vom UI-Thread (User-Interface) aufgerufen werden , während sie doInBackground()auf einem anderen Thread ausgeführt wird. Dies ist der Hauptgrund, warum sie AsyncTaskentworfen wurde.

Sie müssen show()entweder anrufen onProgressUpdate()oder anrufen onPostExecute().

Zum Beispiel:

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
quelle
3
Das hat mir nicht geholfen, sondern nur "AlertDialog.Builder builder = new AlertDialog.Builder (context);" und fügte die Konfiguration des Builders hinzu. Der Versuch, dies im onProgressUpdate anzuzeigen, führt zu genau demselben Fehler. Irgendwelche Ideen ?
Ins0m
Vielen Dank an Konstantin, ich wusste nicht, dass Sie onProgressUpdate mit PublishProgress () mit jedem Variablentyp überschreiben können. Hat mir wirklich geholfen, einfach mit Toastnachrichten zu aktualisieren.
Wired00
81

Ich hatte ein ähnliches Problem, aber als ich diese Frage las, dachte ich, ich könnte auf einem UI-Thread laufen:

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

Scheint den Trick für mich zu tun.

Hyui
quelle
getActivity (). runOnUiThread (this :: mymethod); Danke hat sehr gut funktioniert.
Mortezahosseini
1

Es fiel mir auch schwer, diese Arbeit zu machen. Die Lösung für mich bestand darin, sowohl hyui als auch konstantin Antworten zu verwenden.

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
quelle
Ich dachte, Dinge, die in erledigt onProgressUpdate()wurden, würden automatisch auf dem UI-Thread ausgeführt
Jemand irgendwo
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
quelle