1

I use AsyncTask in combination with a ProgressDialog. See my code, I have a problem in onPostExecute. If the task is running for the first time it get a Null Poiter Exception for progressDialog in handleMessage but calling dismiss() direct would work. When I turn the phone before onPostExecute is reached, progressDialog.dismiss() does not work. why does the handler not always work?

public class UpdateTask extends AsyncTask<Void, Void, Void> {
    private ProgressDialog progressDialog;
    private Handler handler;

public UpdateTask(Act activity) {

        progressDialog = ProgressDialog.show(Activity.this, "Wait",
                "Wait");
        progressDialog.dismiss();

        handler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                //run on UI Thread
                switch( msg.what ){
                    case MSG:                       
                        progressDialog.show();
                        break;
                    case DETACH:
                        progressDialog.dismiss();
                        break;  
                }
            }
        }; 

    }


    void detach() {
          activity=null;
                  //problematic
          //progressDialog.dismiss();
          //handler.sendEmptyMessage(DETACH);
        }




    @Override
    protected Void doInBackground(Void... params) {
        handler.sendEmptyMessage(MSG);;
        return null;
    }

    protected void onPostExecute(Void result)    {  
        if (activity==null) {
            Log.w("RotationAsync", "onPostExecute() skipped -- no activity");
          }
          else {
              //problematic
              //                  progressDialog.dismiss();
              handler.sendEmptyMessage(MSG);
                progressDialog = null;
          }
    }

};
user1324936
  • 2,187
  • 4
  • 36
  • 49

2 Answers2

4

Any reason why you need the Handler inside the AsyncTask? If you want to control your progress dialogue from an AsyncTask using a Handler is the correct way, however, your current Handler would get created and destroyed each time you start a new UpdateTask. If you define your handler outside your AsyncTask, something like:

private Handler handler = new Handler(new Handler.Callback() {
    @Override
public boolean handleMessage(Message msg) {

    switch( msg.what ){
                case MSG:                       
                    progressDialog.show();
                    break;
                case DETACH:
                    progressDialog.dismiss();
                    break;  
            }

    return false;
}
});

Now you can call handler.sendEmptyMessage(what) from any background thread safely, and the progressDialog will update on the UI thread only. Not a complete fix, and I don't know what int values you have defined for DETACH and MSG. But hopefully it will help. This is the method I use to update any UI element from a background task. Just do a bit more reading about the AsyncTask and updating UI elements.

digiphd
  • 2,319
  • 3
  • 23
  • 22
2

See https://stackoverflow.com/a/4538370/719212
And you should read about onPreExecute() in Android documentation.

Gibolt
  • 42,564
  • 15
  • 187
  • 127
ductran
  • 10,043
  • 19
  • 82
  • 165