【问题标题】:Kindle Fire: PopupMenu$OrientationChangeListener leakKindle Fire:弹出菜单$方向更改侦听器泄漏
【发布时间】:2012-10-22 04:58:39
【问题描述】:

我有一个小弹出菜单,它锚定在操作栏中的按钮上。这适用于 3.0/3.1 Xoom 和 Galaxy 标签,以及 4.1 Nexus 7。

但是,在 7" Fire HD (this one) 上,我在退出应用程序时收到有关意图接收器泄漏的错误。只有在运行期间未打开菜单时才会出现该错误。

the one copy of the source I've found 中没有提到OrientationChangeListener;我怀疑亚马逊有不同的实现。

问题

  • 有人遇到过这种情况吗?
  • 有人知道解决方法或修复方法吗?
  • (在哪里)我可以找到亚马逊的源代码?
  • 最后,(颤抖)我在应用程序退出时不泄漏接收器有多重要?

这里是菜单xml:

<?xml version="1.0" encoding="utf-8"?>
<menu
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_profile"
        android:title="@string/menu_item_profile" 
        ></item>
    <item android:id="@+id/menu_logout"
        android:title="@string/menu_item_logout"
        ></item>

</menu>

这是我注册的地方:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_menu, menu);

    MenuItem login = menu.findItem(R.id.menu_login);
    Button button = (Button) login.getActionView().findViewById(R.id.login);
    button.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            profileMenu.show();
        }
    });


    // profileMenu is an instance field
    profileMenu = new PopupMenu(this, button);
    inflater.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 all and the problem persists
            return false;
        }
    });

    return true;
}

这是完整的堆栈跟踪:

10-21 20:55:28.461: E/ActivityThread(4526): Activity **.app.ListActivity has leaked IntentReceiver android.widget.PopupMenu$OrientationChangeListener@422d77e0 that was originally registered here. Are you missing a call to unregisterReceiver()? 
10-21 20:55:28.461: E/ActivityThread(4526): android.app.IntentReceiverLeaked: Activity **.app.ListActivity has leaked IntentReceiver android.widget.PopupMenu$OrientationChangeListener@422d77e0 that was originally registered here. Are you missing a call to unregisterReceiver()? 
10-21 20:55:28.461: E/ActivityThread(4526):     at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:826) 
10-21 20:55:28.461: E/ActivityThread(4526):     at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:621) 
10-21 20:55:28.461: E/ActivityThread(4526):     at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1072) 
10-21 20:55:28.461: E/ActivityThread(4526):     at android.app.ContextImpl.registerReceiver(ContextImpl.java:1059) 
10-21 20:55:28.461: E/ActivityThread(4526):     at android.app.ContextImpl.registerReceiver(ContextImpl.java:1053) 
10-21 20:55:28.461: E/ActivityThread(4526):     at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:357) 
10-21 20:55:28.461: E/ActivityThread(4526):     at android.widget.PopupMenu.<init>(PopupMenu.java:81) 
10-21 20:55:28.461: E/ActivityThread(4526):     at **.app.ListActivity.onCreateOptionsMenu(ListActivity.java:350) 
10-21 20:55:28.461: E/ActivityThread(4526):     at android.app.Activity.onCreatePanelMenu(Activity.java:2558) 
10-21 20:55:28.461: E/ActivityThread(4526):     at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:398) 
10-21 20:55:28.461: E/ActivityThread(4526):     at com.android.internal.policy.impl.PhoneWindow.invalidatePanelMenu(PhoneWindow.java:883) 
10-21 20:55:28.461: E/ActivityThread(4526):     at com.android.internal.policy.impl.PhoneWindow$2.run(PhoneWindow.java:3008) 
10-21 20:55:28.461: E/ActivityThread(4526):     at android.os.Handler.handleCallback(Handler.java:605) 
10-21 20:55:28.461: E/ActivityThread(4526):     at android.os.Handler.dispatchMessage(Handler.java:92) 
10-21 20:55:28.461: E/ActivityThread(4526):     at android.os.Looper.loop(Looper.java:137) 
10-21 20:55:28.461: E/ActivityThread(4526):     at android.app.ActivityThread.main(ActivityThread.java:4491) 
10-21 20:55:28.461: E/ActivityThread(4526):     at java.lang.reflect.Method.invokeNative(Native Method) 
10-21 20:55:28.461: E/ActivityThread(4526):     at java.lang.reflect.Method.invoke(Method.java:511) 
10-21 20:55:28.461: E/ActivityThread(4526):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
10-21 20:55:28.461: E/ActivityThread(4526):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
10-21 20:55:28.461: E/ActivityThread(4526):     at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

    标签: android memory-leaks kindle-fire


    【解决方案1】:

    我通过在第一次按下锚按钮时创建 PopupMenu 解决了这个特殊问题。由于泄漏仅发生在显示菜单之前退出活动时,我认为消除该状态是一个不错的选择。

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        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) {
                    profileMenu = new PopupMenu(ListActivity.this, button);
                    inflater.inflate(R.menu.profile_menu, profileMenu.getMenu());
                    profileMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                        public boolean onMenuItemClick(MenuItem item) {
                            // do something with item
                            return false;
                        }
                    });
                }
                profileMenu.show();
            }
        });
        return true;
    }
    

    还有一种边缘情况会导致 PopupMenu 的窗口泄漏。我将在一个新问题中发布它并很快将其链接到此处。不过,如果不从头开始重新实现 PopupMenu,我认为我无法解决这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-13
      • 1970-01-01
      • 2011-06-27
      • 1970-01-01
      • 2013-12-20
      • 2015-10-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多