Подтвердить что ты не робот

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

Ответ 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);
}