2012-06-28 4 views
31

Sto definendo le voci di menu in XML e sto tentando di utilizzare l'attributo onClick aggiunto in API 11. Quando l'attività viene avviata in un emulatore in esecuzione 4.0.3, il seguenti eccezioni si verificano:InflateException: Impossibile risolvere la voce di menu sul gestore di clic.

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) 

non capisco che cosa sta causando l'eccezione, in quanto il metodo seguente è definito nella mia attività

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

mio file di definizione del menu XML contiene:

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

Per compatibilità all'indietro Sto usando ActionBarSherlock e ricevo anche un'eccezione molto simile quando eseguo l'app su 2.3.x.

Questa è una versione più completa della pila traccia

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

Ho lo stesso problema e sembra essere correlato all'applicazione di un tema personalizzato a ActionBarSherlock, anche se non sono sicuro ... Stai utilizzando un tema personalizzato? – Zharf

+0

Sì, sto usando un tema personalizzato. –

+1

Sì, questo succede per me su un dispositivo 4.0.3 reale, ma non sull'emulatore 4.1. Posso solo supporre che sia un bug in Android che è stato riparato da allora. Non sto usando ActionBarSherlock. – Timmmm

risposta

0

ho scoperto che ho avuto lo stesso problema con le voci di menu ActionBar, ed i loro eventi onClick. Quello che ho scoperto è che la workstation che sto sviluppando aveva esaurito la memoria e aveva bisogno di essere riavviata. La VM di Android è ora in grado di risolvere il nome del metodo a cui si fa riferimento.

+0

, quando ho riavviato, non mi sono reso conto che il VM Android che è venuto fuori era 2.3.3. Tuttavia, quando ho selezionato specificamente che Android VM è 4.0.3, ho continuato a ricevere l'errore per onClick. – user1418015

+0

ho trovato una risposta che può aiutare (o almeno gli altri) ... – user1418015

+0

@Override public boolean onCreateOptionsMenu (menu Menu) { getMenuInflater() gonfiare (R.menu.activity_main, menu).; MenuItem item = menu.findItem (R.id.menu_open); if (item == null) \t return true; item.setOnMenuItemClickListener ( \t \t nuova MenuItem.OnMenuItemClickListener() \t \t { \t \t pubblico onMenuItemClick booleana (MenuItem articolo) \t \t \t {return (showDirectory (voce));} \t \t} ) ; return true; } – user1418015

0
@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); 
} 
+0

basato su questa discussione .. http://stackoverflow.com/questions/6150080/set-a-menu-item-as-checked-from-code .. si suggerisce che i programmatori aggiornino i menu usando menu.findItem () vs findItemById(). Per fare ciò, l'opzione di menu viene mantenuta in onCreateOptionsMenu o onPrepareOptionsMenu .. discussa qui. Http://developer.android.com/guide/topics/ui/menus.html – user1418015

+0

L'altra cosa che penso stia accadendo con il file XML è che il campo onClick non può essere risolto con un metodo che soddisfa i criteri appropriati ... dovrebbe essere ... pubblico void [eventName] (MenuItem item) {} o booleano pubblico [eventName] (voce MenuItem) {}. Nemmeno se sembra funzionare. – user1418015

68

Ho trovato una soluzione che ha funzionato per me. Di solito l'attributo onClick in un layout ha il seguente metodo di

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

Su una voce di menu (in questo menu Sherlock caso) dovrebbe seguire la seguente firma:

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

Così, il vostro problema era che il tuo metodo ha restituito void e non boolean.

1

Nel mio caso il problema era che avevo siaonClick nel mio menù XML e un onCreateOptionsMenu nella mia attività. Il mio onClick era in realtà difettoso (perché indicava metodi inesistenti) ma inizialmente non l'avevo notato perché stavo testando su Android 2.x, dove onClick non è supportato e ignorato. Una volta provato su 4.x, ho iniziato a ricevere questo errore.

Quindi, in pratica, non utilizzare onClick se si pianifica la distribuzione in Android 2.x. Ignora silenziosamente i tuoi valori onClick finché non provi a eseguire 3.0+.

+0

Matt, stai usando ABS? –

+0

No. Cos'è l'ABS? –

+0

ActionBarSherlock –

16

Nel mio caso, il AndroidManifest.xml della mia applicazione (avviato dall'assistente Eclipse predefinito) conteneva android:theme="@style/AppTheme" nel blocco <application>.

Quando il debug la causa del problema, si è scoperto che la linea

mMethod = c.getMethod(methodName, PARAM_TYPES); 

in android.view.MenuInflater/InflatedOnMenuItemClickListener è stato richiamato con c non essendo la mia classe Activity ma una dubbia android.view.ContextThemeWrapper (che ovviamente non contiene l'onClick handler).

Quindi, ho rimosso il android:theme e tutto ha funzionato.

+2

Questo è interessante in quanto sembra che questa sia stata la causa del mio problema. Tuttavia, chiunque abbia bisogno (o desideri) del set di temi finirebbe con questo problema (su API 14/15, non API 16+ da quello che posso dire). Pertanto, la mia soluzione era quella di abbandonare l'assegnazione onClick e aggiungere semplicemente le chiamate al metodo onOptionsItemSelected(). – lilbyrdie

8

Anche se questo è un po 'obsoleto, ecco il motivo dell'eccezione. Quando si guarda nelle fonti di API Android 15 (4.0.3-4.0.4) nella classe MenuInflater si vedrà questo metodo:

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; 
} 

Questo è stato l'eccezione accade, come Junique già sottolineato. Tuttavia la rimozione del tema dell'app è solo una soluzione alternativa e nessuna opzione reale. Come vediamo il metodo tenta di trovare il metodo Callback sulla classe dell'oggetto di contesto passato. Quindi, invece di chiamare getMenuInflater() in onCreateOptionsMenu devi chiamare new MenuInflater(this), in modo che this venga passato come un contesto e quindi il codice funzionerà.

È comunque possibile utilizzare getMenuInflater() per le altre versioni di API se si utilizza un'istruzione if in questo modo:

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

Io in realtà non so se il bug si verifica nelle versioni API sotto 15 troppo, quindi ho solo generalmente usato la versione di salvataggio.