0

I've been to get rid of a ProgressDialog for some time now. After some googling and reading through questions on stackoverflow I round that I can only run ProgressDialog.dismiss() from the UI Thread. After some more reading I learned I need to create a handler and attach it to the UI Thread like this: new Handler(Looper.getMainLooper()); but alas, the stubborn ProgressDialog still refuses to die.

Here's what my code looks like:

/* Members */
private ProgressDialog mProgressDialog;
private Handler mHandler;

/* Class' constructor method */
public foo() {
    ...
    this.mHandler = new Handler(Looper.getMainLooper());
    ...
}

/* The code that shows the dialog */
public void startAsyncProcessAndShowLoader(Activity activity) {
    ...
    mProgressDialog = new ProgressDialog(activity, ProgressDialog.STYLE_SPINNER);
    mProgressDialog.show(activity, "Loading", "Please wait...", true, false);
    doAsyncStuff(); // My methods have meaningful names, really, they do
    ...
}

/* After a long process and tons of callbacks */
public void endAsyncProcess() {
    ...
    mHandler.post(new Runnable() {
        @Override
        public void run() {
            Log.d(TAG, "Getting rid of loader");
            mProgressDialog.dismiss();
            mProgressDialog = null;
            Log.d(TAG, "Got rid of loader");
        }
    });
    ...
}

This doesn't seem to work, debugging shows that certain members of the PorgressDialog (mDecor) are null. What am I missing?

Ron
  • 1,989
  • 2
  • 17
  • 33
  • Some questions here - Paste the whole class name (definition, implements, extends etc. What's "activity" correcponding to? Isn't the visibility of `mProgressDialog` limited to just `startAsyncProcessAndShowLoader()` ? – g00dy Aug 29 '13 at 09:21
  • what is the error you are getting? – Ritesh Gune Aug 29 '13 at 09:24
  • Whoops, forgot to include the activity parameter. activity is passed to `foo.startAsyncProcessAndShowLoader()` when you want to start the process and is the activity in which you're calling it, i.e., you call it using `foo.startAsyncProcessAndShowLoader(this)`. – Ron Aug 29 '13 at 09:30
  • @ronmrdechai: even if your code works now, there is a pattern for this: AsyncTask. See my answer below. – flx Aug 31 '13 at 02:46

3 Answers3

1

You should use the AsyncTask to do your async task:

AsyncTask task = new AsyncTask<Void, Void, Void>() {
    private Dialog mProgressDialog;

    protected void onPreExecute() {
        mProgressDialog = new ProgressDialog(activity, ProgressDialog.STYLE_SPINNER);
        mProgressDialog.show(activity, "Loading", "Please wait...", true, false);
    }

    protected Void doInBackground(Void... param) {
        doAsyncStuff(); // My methods have meaningful names, really, they do
        return null;
    }

    protected void onPostExecute(Void result) {
        mProgressDialog.dismiss();
    }
};
task.execute(null);
flx
  • 14,146
  • 11
  • 55
  • 70
0
progressDialog.setCancelable(true);
progressDialog.setOnCancelListener(new OnCancelListener() {

    public void onCancel(DialogInterface dialog) {
    Log.d(TAG, "Got rid of loader");
    }
});
Dyna
  • 2,304
  • 1
  • 14
  • 25
0

Try this:

public static final int MSG_WHAT_DISMISSPROGRESS = 100;
Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg){
        swtich(msg.what){
            case MSG_WHAT_DISMISSPROGRESS:
                mProgressDialog.dismiss();
            break;
        }
    }
}

public void endAsyncProcess(){
    handler.obtainMessage(MSG_WHAT_DISMISSPROGRESS).sendToTarget();
}
happyhls
  • 121
  • 3