1

在我的一个活动中,选项菜单出现了一个奇怪的行为:当用户从活动中导航离开(但没有完成)并再次返回然后调用选项菜单时,应用程序崩溃并显示IllegalStateException. 只有在离开活动之前已经显示菜单时才会抛出异常。似乎不是我的代码导致了这种情况。活动是一个ListActivity。首先,我认为我Adpater可能会导致这种情况,但异常来自创建选项菜单(面板)的内部。

更奇怪的是,这并不是在所有设备上都发生。目前我只能在装有 Android 4.0.3 的 HTC Sensation 上重现这一点。

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
    at android.view.ViewGroup.addViewInner(ViewGroup.java:3345)
    at android.view.ViewGroup.addView(ViewGroup.java:3216)
    at android.view.ViewGroup.addView(ViewGroup.java:3196)
    at com.android.internal.policy.impl.PhoneWindow.openPanel(PhoneWindow.java:614)
    at com.android.internal.policy.impl.PhoneWindow.onKeyUpPanel(PhoneWindow.java:884)
    at com.android.internal.policy.impl.PhoneWindow.onKeyUp(PhoneWindow.java:1557)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1884)
    at android.view.ViewRootImpl.deliverKeyEventPostIme(ViewRootImpl.java:3407)
    at android.view.ViewRootImpl.handleFinishedEvent(ViewRootImpl.java:3380)
    at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2523)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:4945)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    at dalvik.system.NativeStart.main(Native Method)

创建选项菜单看起来很基本(和我的所有其他活动一样,这不会造成任何问题):

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.message_thread, menu);
    return true;
 }

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);

    MenuItem item = menu.findItem(R.id.menuItemToContacts);
    // enable/disable some items ...

    return true;
}

对应的 menu.xml 如下所示。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:id="@+id/menuItemSettings"
        android:icon="@drawable/ic_menu_einstellungen"
        android:title="@string/settings">
    </item>
    <!-- some more elements in the exact same style -->
</menu>

我已经尝试了很多(尤其是在创建和准备菜单方面)。最大的问题是,我无法在任何地方捕捉到异常,因为它是从一些View.

非常感谢提示和可能的工作轮次!!1!


在我的Adapter我实际上做了一些视图的东西,但我认为我在添加视图时很小心。此外,该异常不包括对我的类的任何跟踪,因此我怀疑它是否真的是导致此问题的适配器。

private class ViewHolder {
    public LinearLayout stateList;
    // more view elements
}

private class ChildContainer {

    public void bind(ViewHolder holder) {
        // prepare listeners and save reference to holder
    }

   /**
     * Populates the view
     */
    private void fillStateLists() {
       // ...
       if (convertView == null) {
        try {
            this.holder.stateList.addView(view);
        } catch (IllegalStateException e) {
            if (view.getParent() instanceof ViewGroup) {
                ((ViewGroup) view.getParent()).removeView(view);
            }
            this.holder.stateList.addView(view);
        }
        }
    }
}

My在sViewHolder中被调用:AdapterbindView()

final ViewHolder holder = (ViewHolder) view.getTag();
final long viewID = getItemId(cursor.getPosition());
final ChildContainer child = this.childContainers.get(viewID);
child.bind(holder);
4

2 回答 2

1

我认为创建选项菜单没有任何问题。它可以在适配器代码中。

于 2012-10-30T13:03:14.040 回答
0

由于某些(愚蠢的)原因onSaveInstanceState被调用onStop以保存列表视图的滚动位置。另外onRestoreInstanceState被叫进来onStart

查看超级实现会发现视图层次结构状态得到保存和恢复。额外的调用可能会导致无效状态,特别是对于选项面板,当再次需要面板时,一切都崩溃了。

删除这些调用并确保保存我的状态仅在修复问题时发生onSaveInstanceState并分别恢复onRestoreInstanceState

永远不要破坏 Activity 生命周期!;-)

于 2012-11-01T09:46:53.247 回答