androidmemory-leaksdialogkilldismiss

Android Dialog dialog (activity context) not dismissed when activity is killed in background


This one is fairly simple, so I hope I get an answer I have an Activity which displays dialogs using both fragments (dismiss is easy to handle in fragment) and the classic Dialog dialog (Context c) where context is the activity context I get in onCreate() using mContext = this

Now, if I activate the developer's option to kill all activities in background, whenever I hit the home button while the dialog is displayed, the dialog is never dismissed and I get a Memory Leak error in Android Studio log cat.

To create the dialog in main activity:

private Dialog mDialog = null; // I want to get rid of these references
private void showDialog() {
    final Dialog dialog = new Dialog(mContext, mParams.applicationTheme);
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.setContentView(R.layout.common_dialog);
    mDialog = dialog;

    // set title and text message of dialog
    // set button_ok and button_cancel from resources

    button_ok.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View view) {
            // do some stuff
            dialog.dismiss();
            mDialog = null;
        }
    });

    button_cancel.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View view) {
            dialog.dismiss();
            mDialog = null;
        }
    });

    dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
        @Override
        public void onCancel(DialogInterface dialogInterface) {
            button_cancel.performClick();
        }
    });

    dialog.show();
}
private Context mContext;
@Override
public void onCreate(Bundle savedInstanceState) {
    mContext = this;
    super.onCreate(savedInstanceState);
}

The only way to avoid memory leak error in Android Studio when activity is killed in background is to keep a reference to the dialog and dismiss it in onDestroy():

onDestroy() {
    if (mDialog != null && mDialog.isShowing())
        mDialog.dismiss();
    super.onDestroy();
}

I thought that the Dialogs created with activity context are destroyed when the activity is destroyed, but this is not the case when the activity is killed in background, unless I am implementing it wrong.

Is there a simpler way than having to hold a reference of every single dialog ?

Notice: I properly handle the dialogs state in onConfigurationChanged() and I don't need to handle the dialogs when activity is killed in these dialogs


Solution

  • the problem only occurs when the "Developer option" is enabled

    In that case, I would not worry about it. Developer options like that do unnatural things that will not happen to ordinary users.

    Personally, I use a DialogFragment rather than a bare Dialog, but otherwise I see nothing out of the ordinary with your code other than your use of requestWindowFeature(Window.FEATURE_NO_TITLE), which should not result in a real-world memory leak.