Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PopupMenu PopupWindow$PopupViewContainer leak

I have a PopupMenu anchored to a button in the Action Bar, and I'm getting log output about a leaked window.

This occurs if my activity is stopped while the PopupMenu is open.

I posted a related question here, but I've solved that issue.

I've seen some similar questions, like this, but none related to PopupMenu.

I'm thinking if I can get a handle on the mentioned PopupWindow$PopupViewContainer then I could remove it from the WindowManager during onPause or something like that, but I don't know how to get at it. The interface exposed by PopupMenu is pretty limited.

  • Has anyone encountered this issue?
  • Has anyone fixed it or worked around it?
  • Anybody know how to get the PopupMenu's View or Window?

This is how I create the menu:

// in Activity
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    final MenuInflater inflater = getMenuInflater();

    inflater.inflate(R.menu.main_menu, menu);
    MenuItem login = menu.findItem(R.id.menu_login);
    final Button button = (Button) login.getActionView().findViewById(R.id.login);

    button.setOnClickListener(new View.OnClickListener() {
        public void onClick(View item) {
            if (profileMenu == null) {
                // I've tried passing getApplicationContext() here too, with no change
                profileMenu = new PopupMenu(ListActivity.this, button);
                profileMenu.getMenuInflater().inflate(R.menu.profile_menu, profileMenu.getMenu());
                profileMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                    public boolean onMenuItemClick(MenuItem item) {
                        // there was code here, but I removed it and problem persists
                        return false;
                    }
                });
            }
            profileMenu.show();

        }
    });

Here is the full stack trace:

10-24 11:10:13.878: E/WindowManager(2048): Activity **.app.ListActivity has leaked window android.widget.PopupWindow$PopupViewContainer@4157a7e8 that was originally added here
10-24 11:10:13.878: E/WindowManager(2048): android.view.WindowLeaked: Activity **.app.ListActivity has leaked window android.widget.PopupWindow$PopupViewContainer@4157a7e8 that was originally added here
10-24 11:10:13.878: E/WindowManager(2048):  at android.view.ViewRootImpl.<init>(ViewRootImpl.java:374)
10-24 11:10:13.878: E/WindowManager(2048):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:292)
10-24 11:10:13.878: E/WindowManager(2048):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
10-24 11:10:13.878: E/WindowManager(2048):  at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149)
10-24 11:10:13.878: E/WindowManager(2048):  at android.widget.PopupWindow.invokePopup(PopupWindow.java:988)
10-24 11:10:13.878: E/WindowManager(2048):  at android.widget.PopupWindow.showAsDropDown(PopupWindow.java:897)
10-24 11:10:13.878: E/WindowManager(2048):  at android.widget.ListPopupWindow.show(ListPopupWindow.java:595)
10-24 11:10:13.878: E/WindowManager(2048):  at com.android.internal.view.menu.MenuPopupHelper.tryShow(MenuPopupHelper.java:127)
10-24 11:10:13.878: E/WindowManager(2048):  at com.android.internal.view.menu.MenuPopupHelper.show(MenuPopupHelper.java:100)
10-24 11:10:13.878: E/WindowManager(2048):  at android.widget.PopupMenu.show(PopupMenu.java:108)
10-24 11:10:13.878: E/WindowManager(2048):  at **.app.ListActivity$3.onClick(ListActivity.java:376)
10-24 11:10:13.878: E/WindowManager(2048):  at android.view.View.performClick(View.java:4084)
10-24 11:10:13.878: E/WindowManager(2048):  at android.view.View$PerformClick.run(View.java:16966)
10-24 11:10:13.878: E/WindowManager(2048):  at android.os.Handler.handleCallback(Handler.java:615)
10-24 11:10:13.878: E/WindowManager(2048):  at android.os.Handler.dispatchMessage(Handler.java:92)
10-24 11:10:13.878: E/WindowManager(2048):  at android.os.Looper.loop(Looper.java:137)
10-24 11:10:13.878: E/WindowManager(2048):  at android.app.ActivityThread.main(ActivityThread.java:4745)
10-24 11:10:13.878: E/WindowManager(2048):  at java.lang.reflect.Method.invokeNative(Native Method)
10-24 11:10:13.878: E/WindowManager(2048):  at java.lang.reflect.Method.invoke(Method.java:511)
10-24 11:10:13.878: E/WindowManager(2048):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
10-24 11:10:13.878: E/WindowManager(2048):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
10-24 11:10:13.878: E/WindowManager(2048):  at dalvik.system.NativeStart.main(Native Method)
like image 223
dokkaebi Avatar asked Oct 24 '12 18:10

dokkaebi


2 Answers

Simply calling profileMenu.dismiss() onStop() would be enough.

like image 137
kleinsenberg Avatar answered Oct 14 '22 05:10

kleinsenberg


For me .dismiss() it in onDestroy() did not help.

It turned out the only way to remove the leaked window problem with PopupMenu was to remove enter/exit transitions I replaced them with popupAnimationStyle instead.

That solved this leaked window problem.

<item name="android:popupEnterTransition">@null</item>
<item name="android:popupExitTransition">@null</item>
<item name="android:popupAnimationStyle">@style/PopupMenuAnimation</item>
    
<style name="PopupMenuAnimation">
    <item name="android:windowEnterAnimation">@anim/slide_up_bottom</item>
    <item name="android:windowExitAnimation">@anim/slide_down_bottom</item>
</style>
like image 34
Per.J Avatar answered Oct 14 '22 07:10

Per.J