当我在显示PopupMenu
时旋转设备时,出现WindowLeaked
错误。
那是我的PopupMenu
:
private void showSelectionMenu(View caller) {
popup = new PopupMenu(this, caller);
// popup.getMenuInflater().inflate(R.menu.selection_menu, popup.getMenu());
popup.inflate(R.menu.selection_menu);
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
Toast.makeText(FileListActivity.this, getString(R.string.selecting)+" "+item.getTitle(), Toast.LENGTH_SHORT).show();
switch (item.getItemId()) {
case R.id.select_all: mediaFolder.selectAll(); break;
case R.id.select_none: mediaFolder.selectNone(); break;
case R.id.select_videos: mediaFolder.selectVideos(); break;
case R.id.select_pictures: mediaFolder.selectImages(); break;
default: break;
}
findViewById(R.id.buttonRenameSelected).setEnabled(mediaFolder.numberSelected>0);
cla.redraw();
return true;
}
});
if (Build.VERSION.SDK_INT >= 14) {
popup.setOnDismissListener(new PopupMenu.OnDismissListener() {
@Override
public void onDismiss(PopupMenu menu) {
Log.d(TAG, "selectionMenu dismissed");
}
});
}
popup.show();
}
我知道这里的许多程序员之前都有同样的错误,通常他们被告知要忽略onDestroy()
中的菜单。我也是这样:
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "FileListActivity onDestroy()");
Log.d(TAG, "onDestroy: popup==null? "+(popup==null));
if (popup != null) { popup.dismiss(); popup = null; }
Log.d(TAG, "onDestroy: popup==null? "+(popup==null));
dataFragment.mRetainedCache = mMemoryCache;
dataFragment.setData(mediaFolder);
}
结果日志包括错误:
02-10 22:24:15.969 D: FileListActivity onDestroy()
02-10 22:24:15.969 D: onDestroy: popup==null? false
02-10 22:24:15.971 D: selectionMenu dismissed
02-10 22:24:15.971 D: onDestroy: popup==null? true
02-10 22:24:16.064 E: android.view.WindowLeaked: Activity com.myApp.FileListActivity has leaked window android.widget.PopupWindow$PopupDecorView{365b288 V.E...... ......ID 0,0-822,1152} that was originally added here
at android.view.ViewRootImpl.<init>(ViewRootImpl.java:418)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:331)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:94)
at android.widget.PopupWindow.invokePopup(PopupWindow.java:1378)
at android.widget.PopupWindow.showAsDropDown(PopupWindow.java:1234)
at android.support.v7.widget.AppCompatPopupWindow.showAsDropDown(AppCompatPopupWindow.java:78)
at android.support.v4.widget.PopupWindowCompatKitKat.showAsDropDown(PopupWindowCompatKitKat.java:30)
at android.support.v4.widget.PopupWindowCompat$KitKatPopupWindowImpl.showAsDropDown(PopupWindowCompat.java:92)
at android.support.v4.widget.PopupWindowCompat.showAsDropDown(PopupWindowCompat.java:171)
at android.support.v7.widget.ListPopupWindow.show(ListPopupWindow.java:680)
at android.support.v7.view.menu.MenuPopupHelper.tryShow(MenuPopupHelper.java:163)
at android.support.v7.view.menu.MenuPopupHelper.show(MenuPopupHelper.java:129)
at android.support.v7.widget.PopupMenu.show(PopupMenu.java:216)
at com.myApp.FileListActivity.showSelectionMenu(FileListActivity.java:434)
at com.myApp.FileListActivity.access$100(FileListActivity.java:44)
at com.myApp.FileListActivity$5.onClick(FileListActivity.java:186)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22433)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6126)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
02-10 22:24:16.079 D: FileListActivity onCreate()
正如您在日志中看到的那样,PopupMenu
(popup
)在错误发生之前被解除并设置为null
。
知道出了什么问题吗?
编辑:
调用showSelectionMenu(View caller)
的地方(在onCreate
中):
Button buttonSelectFiles = (Button) findViewById(R.id.buttonSelectFiles);
buttonSelectFiles.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showSelectionMenu(v);
}
});
编辑2:
我刚刚发现我在运行Android 7.1.1(LineageOS,每晚构建)的Nexus 5上出现了这个错误,但在运行Fire OS 5.3.2.1(基于Android 5)的Fire HD 8上却没有出现此错误三星Galaxy S +运行Android 4.4.4(CyanogenMod 11)。所以也许它只发生在Android 7上,或者LineageOS中有一个错误!? 如果有人拥有官方Android 7,他/她可能会尝试使用此Android Popup Menu Example来引发该错误。您只需添加此代码:
@Override
public void onDestroy() {
super.onDestroy();
if (popup != null) { popup.dismiss(); popup = null; }
}
并使popup
成为一个类成员变量。
编辑3:
这不是LineageOS问题。运行Android 7.1.1的Android Studio模拟器中也会出现此错误。
答案 0 :(得分:0)
当您的代码尝试显示弹出窗口时出现错误。轮换更改后重新创建活动,因此我认为您的caller
参数包含已销毁活动的视图。您应该检查caller
参数的来源,并在必要时重新分配。