问题
Some users tell me about the exception the got:
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)
But I can't understand what can be wrong. Does anyone have some ideas about the problem? I've tried to repeat that exception, but I failed to do this. Here is the code
@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;
}
with app_menu xlm file:
<?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>
回答1:
Like people have said, the bug occurs when there's formatting in the MenuItem title, because of an Android bug in Activity when it writes to the system EventLog.
https://android-review.googlesource.com/#/c/47831/
Although I've only seen it manifest on LG so far, it seems like it will happen in any version of Android before the fix. As far as I can tell from that commit, the earliest release it was tagged in was 4.3, but maybe I'm reading it wrong.
In Activity's onMenuItemSelected, they use MenuItem.getTitleCondensed() which causes the error. I don't use the condensed title anywhere, and as far as I can tell the views that use it by default weren't introduced until v7 support library and we're using v4.
So, my change was to override onMenuItemSelected in a base Activity class and set the condensed title to be a string version of the title. This lets the formatted title be displayed (like with a custom font), and then use the plain string one for event log:
@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);
}
Probably you could just do it in 4.1.2, or just for LG, but it's not clear to me why it hasn't manifest on other versions. It looks like the bug could happen elsewhere. Maybe someone can figure out when it was introduced, but there didn't seem like much downside to needlessly setting an extra string.
回答2:
For those using AppCompat
:
you can't override Activity.onMenuItemSelected()
. If all you need is to apply formatting to MenuItem
's title
and you don't care about titleCondensed
:
CharSequence rawTitle = "Click here";
menuItem.setTitleCondensed(rawTitle);
SpannableString spannableTitle = new SpannableString(rawTitle);
//...whatever formatting on spannableTitle, you want
menuItem.setTitle(spannableTitle);
回答3:
For me this error occurred only for a custom font SpannableString in ActionBar title / subtitle. Removing custom formatting solved the problem.
Hack (sorry 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));
}
回答4:
I had the same problem too. It turned out that I was trying to format my strings.
<string name="send">
<b>Send</b>
</string>
I changed it to:
<string name="send">
Send
</string>
I hope this helps.
You can use CDATA tags also here is a related question link.
<string name="send">
<![CDATA[<b>Send</b>]]>
</string>
Thanks to Travis for pointing this out.
回答5:
I had the same issue, but looking the Android Source Code, I found that the problem occurs when writting an internal Log, which can't print a formatted text.
The solution: simply skip this Log by reimplementing this function and DON'T CALL ITS SUPER!!
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
... // Do your staff
return true;
}
回答6:
I had the same problem
The problem in Android 4.1 with Menu Item is the Strings
Originally, my Menu Item was like this:
<item android:id="@+id/item1" android:title="@string/ic_login"
android:icon="@drawable/ic_login" android:orderInCategory="100" >
</item>
and that didn't work.
I change it into this:
<item android:id="@+id/item1"
android:title="Login"
android:orderInCategory="100"
android:icon="@drawable/ic_login"
/>
and that worked well.
回答7:
there is a "not very good' idea with 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);
}
It's workaround actions like
to set a raw string, overcame a buggy place, set original formatted string back. I concider that formatted string is a SpannableString object in this example, may be you'll use something else
回答8:
I found how to cause this error. In inflate menu, I set title like that
menu.setTitle(Html.fromHtml("Menu line #1<br>And what is displayed on line #2"));
When I use this setting, it will cause invalid payload exception. Then I use
menu.setTitle("Menu line #1. Opps, can not set what is displayed on line #2");
it work fine as when I known Android. I want my menu have 2 lines, so use html tag to break line, but success on only Activity, but falied on another. I don't know what happend. Anyone have another idea or solution?
回答9:
For anyone using the Toolbar with DrawerLayout under Support Library, this issue might occur for them too. This problem can be solved by overriding the default navigation click implementation.
@Override
public void setSupportActionBar(Toolbar toolbar) {
super.setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openDrawer();
}
});
}
This should work.
回答10:
I had the same problem
The problem is in Android 4.1 the Menu Item can't be formated strings
The original string in the strings.xml was using Bold tag in the string and that didn't work. Then I removed the Bold tag and that worked well.
回答11:
Calling setSupportActionBar()
after calling setDisplayHomeAsUp()
also seems to cause this issue. It is recommended to check for multiple setSupportActionBar()
calls, especially in the base classes if they exist.
On deleting the unintended call to setSupportActionBar()
, the problem went away.
来源:https://stackoverflow.com/questions/7658725/android-java-lang-illegalargumentexception-invalid-payload-item-type