Search code examples
androidandroid-activitystaticdialogandroid-context

How can I use dialog from a common class in android


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();
}

}


Solution

  • 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();
    }