【问题标题】:Android: java.lang.IllegalArgumentException: Invalid payload item typeAndroid:java.lang.IllegalArgumentException:有效负载项类型无效
【发布时间】:2011-10-05 08:44:46
【问题描述】:

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

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>

【问题讨论】:

  • onMenuItemSelected() 方法中的第 2452 行是什么?
  • 我只在运行 Android 4.1.2 的 LG 设备上观察到此崩溃
  • 仅供参考:我在 LG P710、LG E460、LG E610 上注意到了此崩溃。它们都在运行 4.1.2。可笑。
  • 我在Samsung GT-S7582 遇到了这个崩溃。安卓版本 4.2.2
  • 也发生在三星 GT-P5100 上 4.2.2

标签: android android-menu illegalargumentexception android-optionsmenu


【解决方案1】:

就像人们说的那样,当 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 执行此操作,但我不清楚为什么它没有在其他版本上显示。看起来这个错误可能发生在其他地方。也许有人可以弄清楚它是什么时候引入的,但是不必要地设置一个额外的字符串似乎没有太大的缺点。

【讨论】:

  • 感谢您的解决方法。但是请注意,传递给此方法的 ActionMenuItem 可能违反 getTitleCondensed() 的 MenuItem 协定,即它可能返回 null。在此处查看 Android 源代码:grepcode.com/file/repository.grepcode.com/java/ext/…
  • 是的,@gnuf 说的。击中后已经在我的代码中修复了它 - 我会更新响应。
【解决方案2】:

对于那些使用AppCompat的人:

您不能覆盖Activity.onMenuItemSelected()。如果您只需要对MenuItemtitle 应用格式并且您不关心titleCondensed

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

    SpannableString spannableTitle = new SpannableString(rawTitle);
    //...whatever formatting on spannableTitle, you want
    menuItem.setTitle(spannableTitle);

【讨论】:

    【解决方案3】:

    对我来说,此错误仅发生在 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));
    }
    

    【讨论】:

    • 嗨 Mateusz,我遇到了同样的错误(总是在 LG 设备上),我们有一个样式化的操作栏标题。一个问题:你得到同样的错误吗?因为堆栈跟踪似乎指向菜单,而不是操作栏标题。如果您还收到错误消息onMenuItemSelected,那么我们可能会遇到与您相同的情况。谢谢!
    • 是的,同样的错误。据我所知,它只发生在 4.1 的 LG 设备上,而且我也收到了带有菜单而不是 ActionBar 的报告。查看我编辑的答案以查看防止此错误的 hack。
    • 感谢您的想法。请注意,您的 hack 将在所有 LG 设备上激活,包括 Nexus 5 和其他设备......也许我们还可以添加条件 Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN 以仅在 Android 4.1 上激活 hack。
    • 我在 Crashlytics 中检查了我只在装有 Android 4.1.2 的 LGE 设备(我猜“LGE”是制造商)上收到错误。
    • 不仅仅出现在 LG 设备上,我有一个三星 GT-I9000 和 Android 2.3.6 也有同样的问题:-/
    【解决方案4】:

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

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

    我改成:

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

    我希望这会有所帮助。

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

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

    感谢 Travis 指出这一点。

    【讨论】:

    • strings.xml 文件中不能有 html,除非它受 CDATA 标签保护。
    【解决方案5】:

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

    解决方案:通过重新实现此函数来跳过此日志并且不要调用它的超级!

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

    【讨论】:

    • 我的活动扩展 android.support.v7.app.ActionBarActivity 并且该方法不能被覆盖,因为它是 final... :(
    【解决方案6】:

    我遇到了同样的问题

    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"
    />
    

    而且效果很好。

    【讨论】:

    • 我的应用有一些活动。它对某人很有效,对另一个人也有同样的问题。不知道为什么?
    【解决方案7】:

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

    【讨论】:

      【解决方案8】:

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

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

      【讨论】:

        【解决方案9】:

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

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

        这应该可行。

        【讨论】:

          【解决方案10】:

          我遇到了同样的问题

          问题在于 Android 4.1 中的菜单项无法格式化字符串

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

          【讨论】:

            【解决方案11】:

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

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

            【讨论】:

              猜你喜欢
              • 2018-01-03
              • 1970-01-01
              • 2017-11-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-02-22
              相关资源
              最近更新 更多