首页 > 解决方案 > 关闭另一个类的自定义对话框

问题描述

我有 3 个类,一个在我的 CustomDialog 类中,另一个是我调用自定义对话框的非活动类,第三个类是我想要关闭自定义对话框的 App 类。

自定义对话框类:

public class DCCView extends Dialog {



private final String dCancel= "CANCEL";
private ResultListener listener;
private Button btnCurrency1;
private Button btnCurrency2;
private Button btnCancel;
private TextView tvCurrency1;
private TextView tvCurrency2;
private TextView tvMsg;
private Handler mTimer;
private Response response;


public DCCView(@NonNull Context context) {
    super(context);
}

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.dcc_interface);
    setCancelable(false);
    btn1 = findViewById(R.id.btn1);
    btn2 = findViewById(R.id.btn2);
    btnCancel = findViewById(R.id.btn_cancel);

    tv1 = findViewById(R.id.tv1);
    tv2 = findViewById(R.id.tv2);
    tvMsg = findViewById(R.id.tv_dcc_msg);

    btnCurrency1.setOnClickListener(view -> {
        response = Response.C1;
        cancelAlert();
        listener.onResult(response);
    });

    btnCurrency2.setOnClickListener(view -> {
        response = Response.C2;
        cancelAlert();
        listener.onResult(response);
    });

    btnCancel.setOnClickListener(view -> {
        response = Response.CANCEL;
        cancelAlert();
        listener.onResult(response);
    });
}

public interface ResultListener {
    void onResult(Response response);
}

public void showDCC(String transCurrency, double transAmount, String dccCurrency, String dccAmount,String dataDisplay, @NonNull ResultListener listener) {
    this.listener = listener;
    Handler hnd = new Handler(getContext().getMainLooper());
    hnd.post(() -> {
        showAlert();
        btn1.setText(transCurrency);
        tv1.setText(String.format("%.2f",transAmount));
        btn2.setText(dccCurrency);
        tv2.setText(dccAmount);
        btnCancel.setText(dCancel);
        tvMsg.setText(dataDisplay);
    });
}

public void showAlert() {
    if (!isShowing()) {
        show();
    }
}

public void cancelAlert() {
    dismiss();
}

非活动类:

public class MSG1002{
    private static DCCView mDccView;

   public MSG1002() {
                Handler hnd = new Handler(App.getContext().getMainLooper());
    hnd.post(() -> {
        mDccView = new DCCView(App.getContext());
    });
   }

   public void process(){
   mDccView.showDCC(transactionCurrency, transA, dccCurrency, dccAmount, dataUserDisplay, (DCCView.Response response) -> {
                onDccResponse(response, socketCliente);
            });
   }
        

应用类:

public class App extends Application{
private static DCCView mDCCView;
public static void realCancelAlert() {
    mDCCView.cancelAlert();
}

@Override
public void onCreate() {
    super.onCreate();
    mContext = getApplicationContext();
    mDCCView =new DCCView(mContext);
}
App.realCancelAlert();

因此,当我从 MSG1002 类调用我的自定义对话框时,对话框会出现并且它可以工作,但是当我使用命令行 App.realCancelAlert(); 从类 App 关闭它时 它没有关闭,我不明白为什么,因为当我调试它时,流程会继续,直到它到达dismiss()并执行它但它并没有消失。

标签: androiddialog

解决方案


警告 显示对话的片段或活动负责关闭它。没有其他班级应该对此负责。否则,您将走上内存泄漏和难以维护的代码的道路。

为什么不关闭?

在您的App类内部onCreate实例化一个类型的对象DCCView并将其存储为该类的静态变量。假设变量现在指向内存地址 0x1234。

然后在代码中的其他地方调用MSG1002类的构造函数。它创建自己的DCCViewas实例new DCCView(App.getContext());并将其存储在MSG1002类静态变量中。假设变量现在指向内存地址 0x5678。

这些变量MSG1002.mDCCViewApp.mDCCView是两个完全不同的变量,它们持有对 . 的两个不同实例的引用mDCCView。这就是为什么它们有不同的地址 0x1234 和 0x5678。试图关闭App.mDCCView你并没有关闭MSG1002.mDCCView对话。

怎么修?

注意:强烈建议不要持有与 UI 相关的静态引用,因为它持有对Context值的引用,并防止它在应该被垃圾收集时被垃圾收集。那就是内存泄漏。

  1. 公开private static DCCView mDCCView;或创建 get/set 方法;
public class App extends Application{
    public static DCCView mDCCView;
    ...
  1. private static DCCView mDccView;MSG1002班级中删除;
  2. 更新MSG1002要使用的类App.mDccView
public class MSG1002{

   public MSG1002() {
       Handler hnd = new Handler(App.getContext().getMainLooper());
       hnd.post(() -> {
           App.realCancelAlert();
           App.mDccView = new DCCView(App.getContext());
       });
   }

   public void process(){
       App.mDccView.showDCC(transactionCurrency, transA, dccCurrency, dccAmount, dataUserDisplay, (DCCView.Response response) -> {
                onDccResponse(response, socketCliente);
            });
   }
   ...
}

有关内存泄漏的更多信息:android中的内存泄漏,导致内存泄漏的对话堆栈溢出问题(9270 个结果)


推荐阅读