【发布时间】:2016-07-27 10:08:38
【问题描述】:
我正在尝试在 Activity 中显示自定义对话框,但出现此错误。我知道为什么here 和here 会出现此错误,并且也知道它的解决方案。但问题是我在我的代码中找不到问题。我花了很多时间在没有运气的情况下找到错误。 我在按钮单击时调用了以下方法
public void changePassword(View view){
DialogChangePassword dialogChangePassword = new DialogChangePassword(ActivityMyAccount.this);
dialogChangePassword.show();
Window window = dialogChangePassword.getWindow();
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
我在此处显示对话框,而 Activity 应该存在。我的问题;
- 我无法在此处关闭对话框,我在
Dialog类中将其关闭。 - 我没有完成活动。如果因为活动结束而发生错误,为什么会结束?
- 如果错误不是因为完成活动,那么为什么会出现此错误?
- 我有一个
NetworkOperation要在 Dialog 类中执行,它与它有什么关系吗?
这是我的 Dialog 类
public class DialogChangePassword extends Dialog {
Context context;
Button confirm, cancel;
CustomEditText edtOldPwd, edtNewPwd, edtConfirmNewPwd;
ProgressDialog progressDialog;
String PASSWORD_INCORRECT_MESSAGE = "Old password is incorrect.";
public DialogChangePassword(Context context) {
super(context);
this.context = context;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.dialog_change_password);
if(progressDialog != null)
progressDialog = null;
progressDialog = new ProgressDialog(context);
progressDialog.setTitle("Please wait...");
progressDialog.setMessage("Updating Password.");
progressDialog.show();
confirm = (Button) findViewById(R.id.btnChangePassword);
cancel = (Button) findViewById(R.id.btnCancel);
edtOldPwd = (CustomEditText) findViewById(R.id.edtOldPassword);
edtNewPwd = (CustomEditText) findViewById(R.id.edtNewPassword);
edtConfirmNewPwd = (CustomEditText) findViewById(R.id.edtConfirmNewPassword);
edtConfirmNewPwd.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (!edtNewPwd.getText().toString().equals(edtConfirmNewPwd.getText().toString()))
edtConfirmNewPwd.setError("Password doesn't match");
}
});
confirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!edtNewPwd.getText().toString().equals(edtConfirmNewPwd.getText().toString())) {
Toast.makeText(context, "Password doesn't match", Toast.LENGTH_SHORT).show();
progressDialog.cancel();
return;
}
HashMap<String, String> params = new HashMap<>();
params.put("email", Utility.classUser.getEmailId());
params.put("password", edtOldPwd.getText().toString());
params.put("newPassword", edtNewPwd.getText().toString());
new NetworkOperation().execute(params);
}
});
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
}
private class NetworkOperation extends AsyncTask<HashMap<String,String>, Void, String> {
@Override
protected String doInBackground(HashMap<String, String>... params) {
try {
ClassAPIRoutes routes = ClassAPIRoutes.initializeRoutes();
return routes.editUserPassword(params[0]);
} catch (final IOException e) {
e.printStackTrace();
getOwnerActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context, e.toString(), Toast.LENGTH_SHORT).show();
}
});
return "error";
}
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
progressDialog.cancel();
dismiss();
if(!s.equals("error")){
JSONObject jsonObject;
try {
jsonObject = new JSONObject(s);
if (jsonObject.get("success").toString().equals("true")) {
Toast.makeText(context, "Password successfully changed.", Toast.LENGTH_SHORT).show();
dismiss();
} else if (jsonObject.get("success").toString().equals("false")) {
if (jsonObject.get("message").toString().equals(PASSWORD_INCORRECT_MESSAGE)) {
Toast.makeText(context, PASSWORD_INCORRECT_MESSAGE, Toast.LENGTH_SHORT).show();
resetFields();
}
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getContext(), s, Toast.LENGTH_SHORT).show();
}
}
}
}
private void resetFields(){
edtOldPwd.setText("");
edtNewPwd.setText("");
edtConfirmNewPwd.setText("");
}
}
【问题讨论】:
-
在完成活动之前关闭您的对话框/进度对话框/警报对话框,您将不会有任何泄漏:)
-
您的对话框包含您活动的上下文。正如@SripadRaj 所说,在完成活动之前关闭你的对话框,也许把它放在 onStop 中。
-
@gitter 我想在更改密码后再次返回活动。为什么活动结束?如果是这样,
DialogChangePassword将被解雇,我将无法更改密码。好吧,我试过了,没有运气 -
嗯。鉴于 AsyncTask 通常因内存泄漏而臭名昭著,因此在对话框中设置 AsyncTask 看起来很容易出错。尝试将您的解雇呼叫移动到 onPostExecute 的末尾一次?
-
我已经在
onPostExecute()内部调用了dismiss()
标签: android memory-leaks dialog