android.view.WindowLeaked 警告对话框的错误原因
android.view.WindowLeaked error cause of alert dialog
我是 android 的新手,我对警报对话框有疑问。
有这样一种方法:
private void deletSelected(){
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle("are you sure?");
dialog.setPositiveButton("Yes" , new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
int deletedRow = getContentResolver().delete(
ContentUris.withAppendedId(CONTENT_URI , selectedRow) , null , null);
if (deletedRow == -1){
Toast.makeText(EditorActivity.this , "not deleted!" , Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(EditorActivity.this , "deleted successfully" , Toast.LENGTH_SHORT).show();
}
if (dialog != null){
dialog.dismiss();
}
}
});
dialog.setNegativeButton("no" , new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
if (dialog != null){
dialog.dismiss();
}
}
});
// Create and show the AlertDialog
AlertDialog alertDialog = dialog.create();
alertDialog.show();
}
还有这样的第二种方法:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// User clicked on a menu option in the app bar overflow menu
switch (item.getItemId()) {
// Respond to a click on the "Save" menu option
case R.id.action_save:
save();
finish();
return true;
// Respond to a click on the "Delete" menu option
case R.id.action_delete:
deletSelected();
finish(); // if i remove this line app will work correctly
return true;
}
return super.onOptionsItemSelected(item);
}
我的问题是,如果我在 onOptionsItemSelected 方法中删除 finish(),我的应用程序将 运行 正确,但它仍处于当前 activity,这是我不想要的。我希望用户在确认对话框中按是后删除数据库中的选定行并返回主 activity 但如果没有此行,选定行将删除但应用程序不会返回到 mainActivity 。
如果我添加 finish(),确认对话框会在单击删除后立即消失,应用程序将返回主 activity 而不会删除任何内容。
逻辑上显示以下错误:
08-04 21:57:02.630 28064-28064/com.example.android.pets E/WindowManager: android.view.WindowLeaked: Activity com.example.android.pets.EditorActivity has leaked window android.widget.PopupWindow$PopupDecorView{652e345 V.E...... ......ID 0,0-588,144} that was originally added here
at android.view.ViewRootImpl.<init>(ViewRootImpl.java:394)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:330)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
at android.widget.PopupWindow.invokePopup(PopupWindow.java:1279)
at android.widget.PopupWindow.showAsDropDown(PopupWindow.java:1118)
at android.support.v7.widget.AppCompatPopupWindow.showAsDropDown(AppCompatPopupWindow.java:105)
at android.support.v4.widget.PopupWindowCompatKitKat.showAsDropDown(PopupWindowCompatKitKat.java:33)
at android.support.v4.widget.PopupWindowCompat$KitKatPopupWindowImpl.showAsDropDown(PopupWindowCompat.java:129)
at android.support.v4.widget.PopupWindowCompat.showAsDropDown(PopupWindowCompat.java:206)
at android.support.v7.widget.ListPopupWindow.show(ListPopupWindow.java:721)
at android.support.v7.view.menu.StandardMenuPopup.tryShow(StandardMenuPopup.java:160)
at android.support.v7.view.menu.StandardMenuPopup.show(StandardMenuPopup.java:187)
at android.support.v7.view.menu.MenuPopupHelper.showPopup(MenuPopupHelper.java:290)
at android.support.v7.view.menu.MenuPopupHelper.tryShow(MenuPopupHelper.java:175)
at android.support.v7.widget.ActionMenuPresenter$OpenOverflowRunnable.run(ActionMenuPresenter.java:803)
at android.os.Handler.handleCallback(Handler.java:743)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:5546)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:682)
08-04 21:57:02.631 28064-28064/com.example.android.pets E/WindowManager: android.view.WindowLeaked: Activity com.example.android.pets.EditorAc
有什么想法吗?
编辑:
删除 finish() 并将其放入 onClick 方法后。现在一切都正确了。但是我不明白这两种方式有什么区别?
尝试将要完成的 activity 传递给 deletSelected()
方法,然后从 onClick()
调用 activity.finish()
,而不是从 finish()
调用你目前在哪里。
用
替换new AlertDialog.Builder(this)
new AlertDialog.Builder(EditorActivity.this);
或使用 getApplicationContext()
发生这种情况是因为当您单击 optionmenuitemselected 时对话框出现后,您正在终止 activity 而没有关闭 AlertDialog。因此,用户无法按他的意愿 select 或按 "yes" 或 "no"。
您需要做的就是将 onBackPressed() 放在警报对话框的肯定按钮或否定按钮中。
private void deletSelected(){
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle("are you sure?");
dialog.setPositiveButton("Yes" , new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
int deletedRow = getContentResolver().delete(
ContentUris.withAppendedId(CONTENT_URI , selectedRow) , null , null);
if (deletedRow == -1){
Toast.makeText(EditorActivity.this , "not deleted!" , Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(EditorActivity.this , "deleted successfully" , Toast.LENGTH_SHORT).show();
}
if (dialog != null){
dialog.dismiss();
}
**// after performing all you task put this
onBackPressed();
// or if you wish to pass some data to previous activity try onActivityResult way.**
}
});
dialog.setNegativeButton("no" , new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
if (dialog != null){
dialog.dismiss();
}
}
});
// Create and show the AlertDialog
AlertDialog alertDialog = dialog.create();
alertDialog.show();
}
就我而言,使用此解决方案成功完成:
使用 dialog.dismiss().
将 "your_activity.this.finish()" 放入空闲时间处理程序中
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
your_activity.this.finish();
}
},500);
我是 android 的新手,我对警报对话框有疑问。 有这样一种方法:
private void deletSelected(){
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle("are you sure?");
dialog.setPositiveButton("Yes" , new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
int deletedRow = getContentResolver().delete(
ContentUris.withAppendedId(CONTENT_URI , selectedRow) , null , null);
if (deletedRow == -1){
Toast.makeText(EditorActivity.this , "not deleted!" , Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(EditorActivity.this , "deleted successfully" , Toast.LENGTH_SHORT).show();
}
if (dialog != null){
dialog.dismiss();
}
}
});
dialog.setNegativeButton("no" , new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
if (dialog != null){
dialog.dismiss();
}
}
});
// Create and show the AlertDialog
AlertDialog alertDialog = dialog.create();
alertDialog.show();
}
还有这样的第二种方法:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// User clicked on a menu option in the app bar overflow menu
switch (item.getItemId()) {
// Respond to a click on the "Save" menu option
case R.id.action_save:
save();
finish();
return true;
// Respond to a click on the "Delete" menu option
case R.id.action_delete:
deletSelected();
finish(); // if i remove this line app will work correctly
return true;
}
return super.onOptionsItemSelected(item);
}
我的问题是,如果我在 onOptionsItemSelected 方法中删除 finish(),我的应用程序将 运行 正确,但它仍处于当前 activity,这是我不想要的。我希望用户在确认对话框中按是后删除数据库中的选定行并返回主 activity 但如果没有此行,选定行将删除但应用程序不会返回到 mainActivity 。
如果我添加 finish(),确认对话框会在单击删除后立即消失,应用程序将返回主 activity 而不会删除任何内容。 逻辑上显示以下错误:
08-04 21:57:02.630 28064-28064/com.example.android.pets E/WindowManager: android.view.WindowLeaked: Activity com.example.android.pets.EditorActivity has leaked window android.widget.PopupWindow$PopupDecorView{652e345 V.E...... ......ID 0,0-588,144} that was originally added here
at android.view.ViewRootImpl.<init>(ViewRootImpl.java:394)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:330)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
at android.widget.PopupWindow.invokePopup(PopupWindow.java:1279)
at android.widget.PopupWindow.showAsDropDown(PopupWindow.java:1118)
at android.support.v7.widget.AppCompatPopupWindow.showAsDropDown(AppCompatPopupWindow.java:105)
at android.support.v4.widget.PopupWindowCompatKitKat.showAsDropDown(PopupWindowCompatKitKat.java:33)
at android.support.v4.widget.PopupWindowCompat$KitKatPopupWindowImpl.showAsDropDown(PopupWindowCompat.java:129)
at android.support.v4.widget.PopupWindowCompat.showAsDropDown(PopupWindowCompat.java:206)
at android.support.v7.widget.ListPopupWindow.show(ListPopupWindow.java:721)
at android.support.v7.view.menu.StandardMenuPopup.tryShow(StandardMenuPopup.java:160)
at android.support.v7.view.menu.StandardMenuPopup.show(StandardMenuPopup.java:187)
at android.support.v7.view.menu.MenuPopupHelper.showPopup(MenuPopupHelper.java:290)
at android.support.v7.view.menu.MenuPopupHelper.tryShow(MenuPopupHelper.java:175)
at android.support.v7.widget.ActionMenuPresenter$OpenOverflowRunnable.run(ActionMenuPresenter.java:803)
at android.os.Handler.handleCallback(Handler.java:743)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:5546)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:682)
08-04 21:57:02.631 28064-28064/com.example.android.pets E/WindowManager: android.view.WindowLeaked: Activity com.example.android.pets.EditorAc
有什么想法吗?
编辑: 删除 finish() 并将其放入 onClick 方法后。现在一切都正确了。但是我不明白这两种方式有什么区别?
尝试将要完成的 activity 传递给 deletSelected()
方法,然后从 onClick()
调用 activity.finish()
,而不是从 finish()
调用你目前在哪里。
用
替换new AlertDialog.Builder(this)
new AlertDialog.Builder(EditorActivity.this);
或使用 getApplicationContext()
发生这种情况是因为当您单击 optionmenuitemselected 时对话框出现后,您正在终止 activity 而没有关闭 AlertDialog。因此,用户无法按他的意愿 select 或按 "yes" 或 "no"。
您需要做的就是将 onBackPressed() 放在警报对话框的肯定按钮或否定按钮中。
private void deletSelected(){
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle("are you sure?");
dialog.setPositiveButton("Yes" , new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
int deletedRow = getContentResolver().delete(
ContentUris.withAppendedId(CONTENT_URI , selectedRow) , null , null);
if (deletedRow == -1){
Toast.makeText(EditorActivity.this , "not deleted!" , Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(EditorActivity.this , "deleted successfully" , Toast.LENGTH_SHORT).show();
}
if (dialog != null){
dialog.dismiss();
}
**// after performing all you task put this
onBackPressed();
// or if you wish to pass some data to previous activity try onActivityResult way.**
}
});
dialog.setNegativeButton("no" , new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
if (dialog != null){
dialog.dismiss();
}
}
});
// Create and show the AlertDialog
AlertDialog alertDialog = dialog.create();
alertDialog.show();
}
就我而言,使用此解决方案成功完成: 使用 dialog.dismiss().
将 "your_activity.this.finish()" 放入空闲时间处理程序中Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
your_activity.this.finish();
}
},500);