Matt Wolfe Matt Wolfe - 24 days ago 16
Android Question

Why won't dismissDialog, removeDialog, or dialog.dismiss work in onDestroy or onPause?

I can't for the life of me figure out how to manage dialogs without using configChanges to specify that you want to manually handle orientation changes.
So lets say you have this AndroidManifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testandroid"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>


Take this MainActivity.java:

package com.example.testandroid;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;

public class MainActivity extends Activity {
private final static String TAG = "MainActivity";
Dialog mDialog = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
setContentView(R.layout.activity_main);
}
public void doShowDialog(View b) {
Log.d(TAG, "doShowDialog");
showDialog(1);
}

private void tryDismiss() {
Log.d(TAG, "tryDismiss");
try {
dismissDialog(1);
removeDialog(1);
mDialog.dismiss();
} catch(IllegalArgumentException ex) {
Log.e(TAG, ex.getMessage());
}
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}

@Override
protected void onPause() {
tryDismiss();
super.onPause();
Log.d(TAG, "onPause");

}
@Override
protected Dialog onCreateDialog(int dialog) {
Builder b = new AlertDialog.Builder(this);
b.setTitle("Hello").setMessage("Waiting..");
mDialog = b.create();
return mDialog;

}
}


and this layout (main.xml)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Open Dialog"
android:onClick="doShowDialog"
/>

</LinearLayout>


It doesn't seem to matter if you call from onDestroy or onPause, the dialog shows back up after the orientation switches. But why? I told it to go away. If call removeDialog/dismissDialog it does nothing when called before the orientation changes. I can't figure out for the life of me why this is. The only way to get rid of this that I know of is to handle the orientation change yourself by using

android:configChanges="keyboardHidden|orientation"


I know the new way of working is to use the FragmentDialog stuff which I have not upgraded to yet and am not ready to rewrite my whole app for that. Just seems strange that this doesn't work.

This is just an example of a real world problem I'm having in my app where the user can request some data be pulled from a remote server (to update a spinner's data), and if they switch orientation the loading dialog will never go away and there seems to be no fix for this besides handling the orientation change with the android:configChanges option. Which I can do but it seems ridiculous to me to have to do that.

-- Update --
Removed the button to dismiss the dialog as it's not necessary and you can't click it anyways since the dialog is on top.

To reproduce just start the app, click the button that opens the dialog, and then rotate your phone.

Answer

Your dialog is saved in onSaveInstanceState, so you might try dismissing it before it's launched:

@Override
protected void onSaveInstanceState(Bundle state)
{
  tryDismiss();
  super.onSaveInstanceState(state);
}

Also I don't really understand why do you use Activity's onCreateDialog to manage dialogs. The reason it was designed was to handle orientation changes automatically. If you want to handle it manually, why don't you just use dialog's functions? Instead of using showDialog(id) and onCreateDialog(id) just launch it directly, it won't reappear after rotating the screen.

    Builder b = new AlertDialog.Builder(this);
    b.setTitle("Hello").setMessage("Waiting..");
    Dialog mDialog =  b.create();
    mDialog.show(); // <-----
Comments