InflateException:无法parsing菜单项onClick处理程序

我使用XML定义菜单项,并尝试使用API​​ 11中添加的onClick属性。在运行4.0.3的模拟器中启动“活动”时,会发生以下exception:

FATAL EXCEPTION: main android.view.InflateException: Couldn't resolve menu item onClick handler onFeedbackMenu in class android.view.ContextThemeWrapper ... Caused by: java.lang.NoSuchMethodException: onFeedbackMenu [interface com.actionbarsherlock.view.MenuItem] at java.lang.Class.getConstructorOrMethod(Class.java:460) 

我不明白是什么导致exception,因为下面的方法是在我的Activity中定义的

 import com.actionbarsherlock.view.MenuItem; ... public void onFeedbackMenu( MenuItem menuItem ) { Toast.makeText( this, "onFeedBack", Toast.LENGTH_LONG ).show(); } 

我的XML菜单定义文件包含:

 <menu xmlns:android="http://schemas.android.com/apk/res/android" > ... <item android:id="@+id/menu_feedback" android:icon="@drawable/ic_action_share" android:showAsAction="ifRoom" android:title="@string/menu_feedback" android:onClick="onFeedbackMenu" /> </menu> 

为了向后兼容,我使用了ActionBarSherlock,并且在2.3.x上运行App时也得到了一个非常相似的exception。

这是堆栈跟踪的更完整版本

 FATAL EXCEPTION: main android.view.InflateException: Couldn't resolve menu item onClick handler onFeedbackMenu in class android.view.ContextThemeWrapper at com.actionbarsherlock.view.MenuInflater$InflatedOnMenuItemClickListener.<init>(MenuInflater.java:204) at com.actionbarsherlock.view.MenuInflater$MenuState.setItem(MenuInflater.java:410) at com.actionbarsherlock.view.MenuInflater$MenuState.addItem(MenuInflater.java:445) at com.actionbarsherlock.view.MenuInflater.parseMenu(MenuInflater.java:175) at com.actionbarsherlock.view.MenuInflater.inflate(MenuInflater.java:97) ... Caused by: java.lang.NoSuchMethodException: onFeedbackMenu [interface com.actionbarsherlock.view.MenuItem] at java.lang.Class.getConstructorOrMethod(Class.java:460) at java.lang.Class.getMethod(Class.java:915) at com.actionbarsherlock.view.MenuInflater$InflatedOnMenuItemClickListener.<init>(MenuInflater.java:202) ... 23 more 

Solutions Collecting From Web of "InflateException:无法parsing菜单项onClick处理程序"

我find了一个适合我的解决scheme。 通常布局中的onClick属性具有以下方法

 public void methodname(View view) { // actions } 

在一个菜单项(在这种情况下,Sherlock菜单)它应该遵循以下签名:

 public boolean methodname(MenuItem item) { // actions } 

所以,你的问题是你的方法返回voidboolean

就我而言,我的应用程序的AndroidManifest.xml (由默认的Eclipse助手启动)在<application>块中包含了android:theme="@style/AppTheme"

当debugging问题的原因时,原来那条线

 mMethod = c.getMethod(methodName, PARAM_TYPES); 

android.view.MenuInflater/InflatedOnMenuItemClickListener被调用不是我的Activity类,但一个可疑的android.view.ContextThemeWrapper (当然不包含onClick处理程序)。

所以,我删除了android:theme和一切工作。

尽pipe这有些过时,但这是例外的原因。 当你在类MenuInflater中查看android API 15(4.0.3-4.0.4)的源代码时,你会看到这个方法:

 public InflatedOnMenuItemClickListener(Context context, String methodName) { mContext = context; Class<?> c = context.getClass(); try { mMethod = c.getMethod(methodName, PARAM_TYPES); } catch (Exception e) { InflateException ex = new InflateException( "Couldn't resolve menu item onClick handler " + methodName + " in class " + c.getName()); ex.initCause(e); throw ex; } 

Junique已经指出,这是例外情况。 然而,删除应用程序的主题只是一个解决方法,没有真正的select。 正如我们所看到的,该方法试图在传递的上下文项的类上findcallback方法。 因此,不要在onCreateOptionsMenu中调用getMenuInflater() ,而应该调用new MenuInflater(this) ,以便将this作为上下文传递,然后代码将工作。

你仍然可以使用getMenuInflater()作为其他api版本,如果你只是使用这样的if语句:

 if (Build.VERSION.SDK_INT > 15) inflater = getMenuInflater(); else inflater = new MenuInflater(this); 

我实际上并不知道这个错误是否发生在15以下的api版本中,所以我通常使用保存版本。

在我的情况下,问题是我在我的菜单XML中onClickonCreateOptionsMenu在我的活动。 我的onClick实际上是错误的(因为它指向不存在的方法),但我没有注意到这一开始,因为我在Android 2.xtesting,其中onClick不支持和忽略。 一旦我在4.xtesting,我开始得到这个错误。

所以基本上,如果你打算在Android 2.x下部署,不要使用onClick 。 它会默默地忽略你的onClick值,直到你尝试运行在3.0以上。

我发现我有与ActionBar菜单项和他们的onClick事件相同的问题。 我发现我正在开发的工作站内存不足,需要重新启动。 Android VM现在能够parsing引用的方法名称。

 @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); MenuItem item = menu.findItem(R.id.menu_open); if (item == null) return true; item.setOnMenuItemClickListener ( new MenuItem.OnMenuItemClickListener () { public boolean onMenuItemClick(MenuItem item) { return (showDirectory(item)); } } ); return true; } public boolean showDirectory (MenuItem item) { CheckBox checkBox = (CheckBox) findViewById (R.id.checkBox1); checkBox.setChecked(true); }