I use a static method from a common class in different activities. The method contains dialog. The dialog fires successfully from various activities. But when I declare the static dialog in the common class android studio warns me not to place Android context classes in static fields (a static reference to DialogChooser which has the field yes pointing to Button); this is a memory leak. How can I use this method containing a static dialog from the common class?
The dialog used in a common class
public class CommonUtility {
public static DialogChooser purchaseDialog;
public static void openDialog(Context context){
purchaseDialog = new DialogChooser(context, context.getString(R.string.message), context.getString(R.string.text_yes), context.getString(R.string.text_no), new DialogClickListener() {
@Override
public void onYesClick(View view) {
Intent i = new Intent(context, ActivityForExample.class);
context.startActivity(i);
purchaseDialog.dismiss();
}
@Override
public void onNoClick(View view) {
purchaseDialog.dismiss();
}
@Override
public void onCrossClick(View view) {
purchaseDialog.dismiss();
}
});
purchaseDialog.show();
}
}
My custom dialog class is
public class DialogChooser extends AppCompatDialog implements View.OnClickListener {
public String message;
public String yesText;
public String noText;
public Window window;
public Button yes, no, cross;
public TextView tvDialogTitle;
public DialogClickListener dialogClickListener;
public DialogChooser(Context activity, String message, String yesText, String noText, DialogClickListener dialogClickListener) {
super(activity);
// TODO Auto-generated constructor stub
this.dialogClickListener = dialogClickListener;
this.message = message;
this.yesText = yesText;
this.noText = noText;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
setContentView(R.layout.custom_dialog);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
window = this.getWindow();
lp.copyFrom(window.getAttributes());
//This makes the dialog take up the full width
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
window.setAttributes(lp);
yes = findViewById(R.id.btn_yes);
no = findViewById(R.id.btn_no);
cross = findViewById(R.id.btn_cross);
tvDialogTitle = findViewById(R.id.txt_dialog);
tvDialogTitle.setText(message);
yes.setText(yesText);
no.setText(noText);
yes.setOnClickListener(this);
no.setOnClickListener(this);
cross.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_yes) {
dialogClickListener.onYesClick(v);
} else if (v.getId() == R.id.btn_no) {
dialogClickListener.onNoClick(v);
} else if (v.getId() == R.id.btn_cross) {
dialogClickListener.onCrossClick(v);
}
dismiss();
}
}
you can't have static
Dialog
or any other class extending/containing Context
, these are momery leaks, thats it. so your architecture/idea is wrong, you should return created dialog to Activity
, which created it, and this Activity
should dismiss it when gets destroyed (onDestroy()
) or maybe even when goes to background (onStop()
)
public static Dialog openDialog(Context context){
DialogChooser purchaseDialog = ...
...
Dialog d = purchaseDialog.create();
d.show();
return d;
}
summary after comments:
public class CommonUtility {
// comment/remove static dependency
//public static DialogChooser purchaseDialog;
public static void openDialog(Context context){
DialogChooser purchaseDialog = ... // local dependency
...
purchaseDialog.show();
}