Android – dismissDialog does not dismiss the dialog-ThrowExceptions

Exception or error:

I am using the showDialog() and dismissDialog() to show progress dialogs in my app. Moved from creating the dialog and calling show() on it to using this in order to save state when changing orientation.

But when I change the orientation from portrait->landscape->portrait, the dismissDialog() no longer dismisses the dialog. The dialog stay there all the time and I need to press the back button for it to disappear.

Any reason why it would behave that way?

Edit

To overcome this issue, I tried adding a removeDialog() in onDestroy() so that the dialog is not created/displayed twice and before orientation change, the dialog is removed. Tried adding log statements and see what happens

05-21 12:35:14.064: DEBUG/MyClass(193): *************callingShowDialog
05-21 12:35:14.064: DEBUG/MyClass(193): *************onCreareDialog

05-21 12:35:15.385: DEBUG/MyClass(193): *************onSaveInstanceState
05-21 12:35:15.415: DEBUG/MyClass(193): *************onDestroy

05-21 12:35:15.585: DEBUG/MyClass(193): *************callingShowDialog
05-21 12:35:15.585: DEBUG/MyClass(193): *************onCreareDialog
05-21 12:35:15.715: DEBUG/MyClass(193): *************onCreareDialog
05-21 12:35:17.214: DEBUG/MyClass(193): *************onSaveInstanceState
05-21 12:35:17.214: DEBUG/MyClass(193): *************onDestroy

05-21 12:35:17.275: ERROR/WindowManager(193): android.view.WindowLeaked: Activity com.android.MyClass has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@43362088 that was originally added here

05-21 12:35:17.395: DEBUG/MyClass(193): *************callingShowDialog
05-21 12:35:17.395: DEBUG/MyClass(193): *************onCreareDialog
05-21 12:35:17.475: DEBUG/MyClass(193): *************onCreareDialog

If we see here, initially when the activity is displayed, the onCreateDialog is called once and on changing the orientation, onSaveInstanceState and onDestroy are called.

But after that, onCreateDialog is called twice (once by a call to showDialog which I make, but why the 2nd time?) and this happens every time I change the orientation hence forth.

Any idea why that happens?

Thanks again

How to solve:

The best solution for me seems to use removeDialog(id) instead of dismissDialog(); Less re-usage this way, but safer (doesn’t throw anything) and no problems when changing orientation.

###

I’ve run into this when showing a dialog in the onCreate override of the Activity. Try moving the code that causes the dialog to be shown into the onPostCreate override instead. This seems to work for me.

###

I wasted over a day on a problem like this with dialogs not being dismissed when calling dismissDialog. It occurred after my first screen rotation and never worked afterwards. I had been using an external AsyncTask which was passed a referenced to the state explicitly.

In the end the solution was really simple…. removeDialog(int) instead of dismissDialog(int).

I had spent what felt like forever proving to myself I was doing the dismiss on the correct activity and checking the number of times things were called etc, but it was caused by some of the jiggerypokery behind the scenes.

###

I recently ran into this problem as well. I have an application with many activities all needing to access global objects (db connections, lists of data, etc) and so I overrode the Application class. To that end, I realized all I needed was a reference to the latest instance of the progress dialog in my runnable that I was using to dismiss the dialog. This is what I came up with and it gracefully survives phone reorientations:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.preferences);

    mHandler = new Handler();
    mApplication = (MyApplication)getApplication();

    mFileStorage = (CheckBoxPreference)getPreferenceScreen().findPreference("fileStorage");

    mProgressDialog = new ProgressDialog(this);

    mProgressDialog.setTitle("Location Update");
    mProgressDialog.setMessage("Moving databases to new storage location.");
    mProgressDialog.setIndeterminate(true);
    mProgressDialog.setCancelable(false);
    mProgressDialog.setCanceledOnTouchOutside(false);

    mApplication.setProgressDialog(mProgressDialog);
}

@Override
protected void onResume() {
    super.onResume();

    mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
    mPreferences.registerOnSharedPreferenceChangeListener(this);

    if (sUpdateThread != null && sUpdateThread.isAlive()) {
        mProgressDialog.show();
    }
}

@Override
protected void onPause() {
    super.onPause();

    mPreferences.unregisterOnSharedPreferenceChangeListener(this);

    if (sUpdateThread != null && sUpdateThread.isAlive()) {
        mProgressDialog.hide();
        mApplication.setProgressDialog(null);
    }
}

….random stuff here….

private Runnable showProgressRunnable = new Runnable() {
    public void run() {
        mProgressDialog.show();
    }
};

private Runnable hideProgressRunnable = new Runnable() {
    public void run() {
        if (mApplication.getProgressDialog() != null) {
            mApplication.getProgressDialog().dismiss();
        }
    }
};

My thread does an mHandler.post(showProgressRunnable) when the task starts and then does an mHandler.post(hideProgressRunnable) when the task finishes. Since the reference to the latest ProgressDialog is now stored in the Application class, I can close it out reliably since I am no longer holding on to an old object reference.

Link for posterity: http://developer.android.com/reference/android/app/Application.html

###

After pressing the home button and navigating to app morelocal (change device language), when I came back to my app, new dialog boxes could not be closed via dismissDialog (I launched the dialog from activity onCreate).

The solution was to call removeDialog instead of dissmissDialog().
This has been recommended by Harri above, many thx.

I have created an Android bug report:

13858


Solution is to create your dialog using OnPostCreate instead of OnCreate. I added that info to the bug report and recommended to improve the dialog documentation.

###

Please be aware that every time you change the orientation, a new instance of your Activity (and consequently of your Dialog via onCreateDialog) is created. You can verify this by adding a log statement in either constructor.

Although difficult to say without having a glance at your code, I’m guessing you’re calling dismissDialog on an older instance of your Activity.

Consider the following Activity that simply shows an empty Dialog when a button is clicked and starts a TimerTask to dismiss it after 10 seconds:

public class Test extends Activity {

    private Dialog dialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);     
        setContentView(R.layout.test);
        Button btn = (Button) findViewById(R.id.testButton);
        btn.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                new Timer().schedule(new TimerTask() {
                    @Override public void run() { dialog.dismiss(); }
                }, 10000);
                Test.this.showDialog(1);
            }
        });
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        if(id == 1) {
            if(dialog == null) { dialog = new Dialog(this); }
            return dialog;
        }
        return super.onCreateDialog(id);
    }
}

This code has a problem similar to the one you’re describing: If – during the 10 seconds – the orientation is changed, the Dialog is never dismissed. Why? Because at the time the TimerTask is run, a whole different set of Test and Dialog instances has been created (during orientation change) and the TimerTask‘s dialog instance variable references a Test instance that is different from the one that is currently active on the screen.

Obviously there are several ways to deal with this issue (mostly depending on your application), one quick (dirty?) way to fix the above code would be to simply make the dialog field static:

private static Dialog dialog;

###

After searching through all kinds of forums, i just did the following:

I call the showDialog(MyDialogID) AND dismissDialog(MyDialogId) out of the handleMessage(myMessage) Method from my Handler.

Before that i called showDialog in my onCreate()-Method and tried to dismiss the dialog in handle-Message. Why this solved the problem, i cant tell.

###

I was experimenting the same issue. I was creating an AlertDialog and a ProgressDialog inside the onCreateDialog() callback and showing them from the onCreate(). Creating these dialogs directly in onCreate (without using onCreateDialog()) and dismissing them in onPause() worked for me!
Based on https://stackoverflow.com/a/5693467/955619

Leave a Reply

Your email address will not be published. Required fields are marked *