29

一些用户告诉我得到的异常:

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>
4

11 回答 11

18

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

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

虽然到目前为止我只在 LG 上看到过它,但它似乎会在修复之前的任何版本的 Android 中发生。据我从该提交中可以看出,它被标记的最早版本是 4.3,但也许我读错了。

在 Activity 的 onMenuItemSelected 中,他们使用了导致错误的 MenuItem.getTitleCondensed()。我不会在任何地方使用精简标题,据我所知,默认使用它的视图直到 v7 支持库才被引入,而我们使用的是 v4。

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

@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,但我不清楚为什么它没有在其他版本上体现。看起来这个错误可能发生在其他地方。也许有人可以弄清楚它是什么时候引入的,但是不必要地设置一个额外的字符串似乎没有太大的缺点。

于 2014-09-04T20:22:28.193 回答
12

对于那些使用AppCompat

你不能覆盖Activity.onMenuItemSelected(). 如果您只需要对MenuItem's应用格式title并且您不关心titleCondensed

    CharSequence rawTitle = "Click here";
    menuItem.setTitleCondensed(rawTitle);

    SpannableString spannableTitle = new SpannableString(rawTitle);
    //...whatever formatting on spannableTitle, you want
    menuItem.setTitle(spannableTitle);
于 2014-02-21T13:51:45.840 回答
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));
}
于 2014-05-23T08:13:17.487 回答
7

我也有同样的问题。原来我正在尝试格式化我的字符串。

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

我将其更改为:

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

我希望这有帮助。

您也可以使用 CDATA 标签,这里是一个相关的问题链接

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

感谢 Travis 指出这一点。

于 2011-10-14T23:06:12.000 回答
3

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

解决方案:通过重新实现这个函数来跳过这个日志并且不要称之为超级!

@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
    ... // Do your staff
    return true;
}
于 2013-04-10T13:50:52.920 回答
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"
/>

效果很好。

于 2012-08-01T15:05:03.093 回答
2

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对象,可能你会使用别的东西

于 2015-11-27T12:33:06.597 回答
1

我找到了导致此错误的方法。在充气菜单中,我设置了这样的标题

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 上成功,但在另一个上失败。我不知道发生了什么。有人有其他想法或解决方案吗?

于 2013-01-12T04:46:06.287 回答
1

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

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

这应该有效。

于 2015-11-03T14:43:46.163 回答
0

我有同样的问题

问题是在 Android 4.1 中的菜单项不能格式化字符串

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

于 2015-04-17T08:04:26.640 回答
0

打电话setSupportActionBar()后打电话setDisplayHomeAsUp()似乎也导致了这个问题。建议检查多个setSupportActionBar()调用,尤其是在基类中(如果存在)。

删除对 的意外调用后setSupportActionBar(),问题就消失了。

于 2016-03-03T10:04:45.137 回答