InflateException: не удалось разрешить пункт меню onClick handler
Я определяю элементы меню в XML и пытаюсь использовать атрибут onClick, добавленный в API 11. Когда действие запускается в эмуляторе с запуском 4.0.3, возникают следующие исключения:
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)
Я не понимаю, что вызывает исключение, поскольку в моей активности определен следующий метод
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.
Это более полная версия трассировки стека
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
Ответы
Ответ 1
Я нашел решение, которое сработало для меня.
Обычно атрибут onClick
в макете имеет следующий метод
public void methodname(View view) {
// actions
}
В пункте меню (в данном случае меню Шерлока) он должен следовать следующей сигнатуре:
public boolean methodname(MenuItem item) {
// actions
}
Итак, ваша проблема заключалась в том, что ваш метод возвратил void
, а не boolean
.
Ответ 2
В моем случае AndroidManifest.xml
моего приложения (начатое стартовым помощником Eclipse) содержало android:theme="@style/AppTheme"
в блоке <application>
.
При отладке причины проблемы оказалось, что строка
mMethod = c.getMethod(methodName, PARAM_TYPES);
в android.view.MenuInflater/InflatedOnMenuItemClickListener
был вызван с c
, не являющимся моим классом Activity
, но сомнительным android.view.ContextThemeWrapper
(который, конечно же, не содержит обработчик onClick).
Итак, я удалил android:theme
, и все сработало.
Ответ 3
Хотя это немного устарело, вот причина исключения. Когда вы изучите источники API android API 15 (4.0.3-4.0.4) в классе MenuInflater, вы увидите этот метод:
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;
}
Это было исключение, как уже указывал Джуник. Однако удаление темы приложения - это всего лишь обходной путь, и никакой реальной возможности. Как мы видим, метод пытается найти метод обратного вызова в классе переданного элемента контекста. Поэтому вместо вызова getMenuInflater()
в onCreateOptionsMenu
вы должны вызвать new MenuInflater(this)
, так что this
передается как контекст, а затем код будет работать.
Вы можете использовать getMenuInflater()
для других версий api, если вы просто используете оператор if, например:
if (Build.VERSION.SDK_INT > 15)
inflater = getMenuInflater();
else
inflater = new MenuInflater(this);
Я действительно не знаю, произошла ли ошибка в api-версиях до 15 лет, поэтому я обычно использовал версию сохранения.
Ответ 4
В моем случае проблема заключалась в том, что в моем меню XML и onCreateOptionsMenu
в моей работе я имел и onClick
. Мой onClick
был действительно неисправен (потому что он указывал на несуществующие методы), но я этого не заметил сначала, потому что я тестировал под Android 2.x, где onClick
не поддерживается и игнорируется. Как только я протестировал на 4.x, я начал получать эту ошибку.
В принципе, не используйте onClick
, если планируете развертывание под Android 2.x. Он будет молча игнорировать ваши значения onClick
, пока вы не начнете работать с версией 3.0 +.
Ответ 5
Я обнаружил, что у меня была та же проблема с элементами меню ActionBar и их событиями onClick. Я обнаружил, что рабочая станция, с которой я развиваюсь, исчерпала память и должна была перезагрузиться. Теперь виртуальная машина Android может разрешить имя метода, на которое ссылаются.
Ответ 6
@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);
}