Android:java.lang.IllegalArgumentException:无效的有效内容项类型

时间:2011-10-05 08:44:47

标签: android android-menu illegalargumentexception android-optionsmenu

有些用户告诉我有关的例外情况:

java.lang.IllegalArgumentException: Invalid payload item type
at android.util.EventLog.writeEvent(Native Method)
at android.app.Activity.onMenuItemSelected(Activity.java:2452)
at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java:846)
at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:153)
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:956)
at com.android.internal.view.menu.IconMenuView.invokeItem(IconMenuView.java:534)
at com.android.internal.view.menu.IconMenuItemView.performClick(IconMenuItemView.java:122)
at android.view.View$PerformClick.run(View.java:11934)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:132)
at android.app.ActivityThread.main(ActivityThread.java:4123)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:491)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
at dalvik.system.NativeStart.main(Native Method)

但我无法理解可能出现的问题。有没有人对这个问题有一些想法?我试图重复那个例外,但我没有做到这一点。这是代码

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

@Override
public boolean onOptionsItemSelected(MenuItem item) {  
   switch (item.getItemId()) {
   case R.id.about:
      startActivity(new Intent(this, AboutActivity.class));
      return true;
   case R.id.settings:
      startActivity(new Intent(this, SettingsActivity.class));
      return true;
   case R.id.help:
      startActivity(new Intent(this, AboutActivity.class));
      return true;
   }

   return true;
} 

使用app_menu xlm文件:

<?xml version="1.0" encoding="utf-8"?>
<menu
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/about"
          android:icon="@android:drawable/ic_menu_info_details"
          android:title="@string/about_menu_item"/>
    <item android:id="@+id/settings"
          android:icon="@android:drawable/ic_menu_preferences"
          android:title="@string/settings_menu_item"/>
</menu>

11 个答案:

答案 0 :(得分:18)

就像人们所说的那样,当MenuItem标题中存在格式化时会出现错误,因为当它写入系统EventLog时,Activity中存在Android错误。

https://android-review.googlesource.com/#/c/47831/

虽然到目前为止我只看到它在LG上出现过,但似乎它会在修复之前的任何版本的Android中出现。据我所知,这个提交最早被发布的版本是4.3,但也许我读错了。

在Activity的onMenuItemSelected中,它们使用MenuItem.getTitleCondensed()导致错误。我没有在任何地方使用精简标题,并且据我所知,默认情况下使用它的视图直到v7支持库才被引入,我们正在使用v4。

因此,我的更改是覆盖基类Activity类中的onMenuItemSelected,并将精简标题设置为标题的字符串版本。这样可以显示格式化的标题(就像使用自定义字体一样),然后使用普通字符串1作为事件日志:

@Override
public final boolean onMenuItemSelected(int featureId, android.view.MenuItem item) {
    // fix android formatted title bug
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2 
            && item.getTitleCondensed() != null) {
        item.setTitleCondensed(item.getTitleCondensed().toString());
    }

    return super.onMenuItemSelected(featureId, item);
}

可能你可以在4.1.2中完成,或者只是为了LG,但我不清楚为什么它没有在其他版本上显示。看起来这个bug可能发生在其他地方。也许有人可以弄明白它什么时候被引入,但似乎没有多少下行不必要地设置一个额外的字符串。

答案 1 :(得分:12)

对于使用AppCompat的人:

您无法覆盖Activity.onMenuItemSelected()。如果您只需要将格式应用于MenuItem的{​​{1}}并且您不关心title

titleCondensed

答案 2 :(得分:9)

对我来说,只有ActionBar标题/副标题中的自定义字体SpannableString才会出现此错误。删除自定义格式解决了这个问题。

哈克(对不起LG ;-):

public static void setActionBarTitle(ActionBarActivity a, String s) {
    SpannableString ss = new SpannableString(s);
    ss.setSpan(new TypefaceSpan(a, "Roboto-Light.ttf"), 0, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    ActionBar actionBar = a.getSupportActionBar();
    actionBar.setDisplayShowTitleEnabled(true);
    actionBar.setLogo(R.drawable.icon);
    actionBar.setTitle(isManufacturer("LG") ? s : ss);
}

public static boolean isManufacturer(String company) {
    String manufacturer = Build.MANUFACTURER;
    String model = Build.MODEL;

    return (manufacturer.contains(company) || model.contains(company));
}

答案 3 :(得分:7)

我也有同样的问题。事实证明我正在尝试格式化我的字符串。

    <string name="send">
        <b>Send</b>
    </string>

我把它改为:

    <string name="send">
        Send
    </string>

我希望这会有所帮助。

您可以使用CDATA标签,这里是相关的question link

        <string name="send">
             <![CDATA[<b>Send</b>]]>
        </string>

感谢Travis指出这一点。

答案 4 :(得分:3)

我有同样的问题,但查看Android源代码,我发现写入内部日志时出现问题,无法打印格式化文本。

解决方案:只需通过重新实现此功能跳过此日志,并且不要调用它超级!!

@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
    ... // Do your staff
    return true;
}

答案 5 :(得分:2)

我遇到了同样的问题

带有菜单项的Android 4.1中的问题是字符串

最初,我的菜单项是这样的:

<item android:id="@+id/item1" android:title="@string/ic_login" 
   android:icon="@drawable/ic_login" android:orderInCategory="100" >
</item>

这不起作用。

我将其更改为:

<item android:id="@+id/item1"
    android:title="Login"
    android:orderInCategory="100"
    android:icon="@drawable/ic_login"
/>

并且运作良好。

答案 6 :(得分:2)

有一个&#34;不太好&#39; onMenuItemSelected(...)

的想法
    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
    if (item.getTitle() instanceof SpannableString) {
        SpannableString sp = (SpannableString)item.getTitle();
        Object[] spans = sp.getSpans(0, sp.length(), Object.class);
        if (spans != null && spans.length > 0) {
            // set text without span markups, need for super.onMenuItemSelected(featureId, item);
            item.setTitleCondensed(sp.toString());
            boolean result = super.onMenuItemSelected(featureId, item);
            item.setTitleCondensed(sp);
            return result;
        }
    }


    return super.onMenuItemSelected(featureId, item);
}

它的解决方法操作如

设置原始字符串,克服错误的地方,设置原始格式化字符串。 我认为格式化字符串在此示例中是 SpannableString 对象,可能是您将使用其他内容

答案 7 :(得分:1)

我发现了如何导致此错误。 在inflate菜单中,我设置了那样的标题

menu.setTitle(Html.fromHtml("Menu line #1<br>And what is displayed on line #2"));

当我使用此设置时,将导致无效的有效负载异常。然后我用

menu.setTitle("Menu line #1. Opps, can not set what is displayed on line #2");

它就像我知道Android时一样正常。 我希望我的菜单有2行,所以使用html标签来打破行,但是只有Activity成功,但是对另一行成功。我不知道发生了什么。任何人都有其他想法或解决方案吗?

答案 8 :(得分:1)

对于在支持库下使用带有DrawerLayout的工具栏的任何人,也可能会出现此问题。可以通过覆盖默认导航单击实现来解决此问题。

@Override
public void setSupportActionBar(Toolbar toolbar) {
    super.setSupportActionBar(toolbar);
    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            openDrawer();
        }
    });
}

这应该有用。

答案 9 :(得分:0)

我遇到了同样的问题

问题出在Android 4.1中,菜单项无法形成字符串

strings.xml中的原始字符串在字符串中使用了Bold标记,但不起作用。然后我删除了Bold标签,效果很好。

答案 10 :(得分:0)

致电setSupportActionBar()后致电setDisplayHomeAsUp()似乎也会导致此问题。建议检查多个setSupportActionBar()调用,特别是在基类中(如果存在)。

在删除对setSupportActionBar()的意外通话时,问题就消失了。

相关问题