I came across the following memory leak example
package com.justinschultz.android;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
public class LeakedDialogActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage("This dialog leaks!").setTitle("Leaky Dialog").setCancelable(false).setPositiveButton("Ok", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which) {}
});
AlertDialog alert = builder.create();
alert.show();
}
}
I don’t understand why it leaks on a rotation. I understand, a new Activity is created while the dialog is still on screen (containing a reference to the old activity). Suppose you close the dialog and rotate again. Shouldn’t the reference to the oldest activity be gone, thus allowing the memory to be reclaimed?
AlertDialogs (if used outside of Fragments) should be instantiated through
onCreateDialog()/showDialog()to avoid leaks.This implementation is deprecated and should be replaced by a DialogFragment, but will work for you:
ADDED
When you don’t create a dialog in
onCreateDialogits essentially not attached to (or owned by) the Activity, and therefore, it’s lifecycle. When the Activity is destroyed or recreated, the Dialog maintains a reference to it.In theory, the Dialog should not leak if you use
setOwnerActivity()and dismiss inonPause()(I believe).I’m not sure you have to worry much about this gotcha as far as general leaks go. Dialogs are kind of a special case.