Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't create handler inside thread that has not called Looper.prepare() inside AsyncTask for ProgressDialog

I don't understand why I'm getting this error. I'm using AsyncTask to run some processes in the background.

I have:

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

When I get into doInBackground() depending on a condition I:

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

Whenever I try downloadSpinnerProgressDialog.show() I receive the error.

Any ideas guys?

like image 527
mlevit Avatar asked Sep 01 '10 02:09

mlevit


People also ask

Why am I getting the same looper exception message from different code?

For those who get the same exception message from different code: What the exception message means is that you are calling the code via a thread that has not prepared Looper. Normally it means you are not calling if from UI thread but you should (OP's case) - a normal thread does not prepare Looper, but UI thread always do.

How do I run a message loop for a thread?

Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare () in the thread that is to run the loop, and then loop () to have it process messages until the loop is stopped.

Why can't I show anything on a UI thread?

Worker threads are meant for doing background tasks and you can't show anything on UI within a worker thread unless you call method like runOnUiThread. If you try to show anything on UI thread without calling runOnUiThread, there will be a java.lang.RuntimeException.


3 Answers

The method show() must be called from the User-Interface (UI) thread, while doInBackground() runs on different thread which is the main reason why AsyncTask was designed.

You have to call show() either in onProgressUpdate() or in onPostExecute().

For example:

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();
    }
}
like image 134
Konstantin Burov Avatar answered Oct 18 '22 22:10

Konstantin Burov


I had a similar issue but from reading this question I figured I could run on UI thread:

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

Seems to do the trick for me.

like image 81
hyui Avatar answered Oct 18 '22 20:10

hyui


I had a hard time making this work too, the solution for me was to use both hyui and konstantin answers,

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

}
like image 1
caiocpricci2 Avatar answered Oct 18 '22 22:10

caiocpricci2