android - 关闭另一个类的自定义对话框
问题描述
我有 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()并执行它但它并没有消失。
解决方案
警告 显示对话的片段或活动负责关闭它。没有其他班级应该对此负责。否则,您将走上内存泄漏和难以维护的代码的道路。
为什么不关闭?
在您的App
类内部onCreate
实例化一个类型的对象DCCView
并将其存储为该类的静态变量。假设变量现在指向内存地址 0x1234。
然后在代码中的其他地方调用MSG1002
类的构造函数。它创建自己的DCCView
as实例new DCCView(App.getContext());
并将其存储在MSG1002
类静态变量中。假设变量现在指向内存地址 0x5678。
这些变量MSG1002.mDCCView
和App.mDCCView
是两个完全不同的变量,它们持有对 . 的两个不同实例的引用mDCCView
。这就是为什么它们有不同的地址 0x1234 和 0x5678。试图关闭App.mDCCView
你并没有关闭MSG1002.mDCCView
对话。
怎么修?
注意:强烈建议不要持有与 UI 相关的静态引用,因为它持有对Context
值的引用,并防止它在应该被垃圾收集时被垃圾收集。那就是内存泄漏。
- 公开
private static DCCView mDCCView;
或创建 get/set 方法;
public class App extends Application{
public static DCCView mDCCView;
...
private static DCCView mDccView;
从MSG1002
班级中删除;- 更新
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 个结果)。
推荐阅读
- list - 如何在列表中使用变量?- 颤动
- java - Gradle 包含 jar 中的文件夹
- testing - 如何编写 Testcafe 选择器('Withoutvalue').withText('Valid Text')?
- java - 无法在黄瓜步骤定义中运行多个线程
- javascript - 我无法在 google-maps-react 库中的 Marker 上获得 onClick 事件
- istio - https/tls 调用的 Istio 请求超时配置
- apache-kafka - Zookeeper 审计禁用后停止工作
- javascript - 如何在 Chrome 扩展程序中存储和更改数据库?
- height - scalaFX - Titledpane:我如何获得内容的高度?
- javascript - onclick 触发器在第一次单击时不起作用