Pergunta

I've a strange problem with a simple view in Android API 15. In this view I've a simple menu with 2 menu items. This code works fine with other Android API but not in this phone with Android 4.0.3:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/root_menu"
        android:icon="@android:drawable/ic_menu_help"
        android:showAsAction="always"
        android:title="Help">
        <menu>
            <item
                android:id="@+id/menu_about"
                android:onClick="aboutDialog"
                android:showAsAction="never"
                android:title="About"/>
        </menu>
    </item>
</menu>

This is the Activity

public class HomeActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.home);
    }

    /**
     * Crea l'action bar
     *
     * @param menu
     * @return
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main_actionbar, menu);
        return true;
    }

    /**
     * Apertura del dialog box con le informazioni sulla versione del programma
     *
     * @param v
     */
    public void aboutDialog(MenuItem v) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("Test")
                .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        // FIRE ZE MISSILES!
                    }
                })
                .setNegativeButton("No", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        // User cancelled the dialog
                    }
                });
        // Create the AlertDialog object and return it
        builder.create().show();
    }
}

So nothing strange in this code. But when I try to run on the device I've this exception:

android.view.InflateException: Couldn't resolve menu item onClick handler 
    aboutDialog in class android.view.ContextThemeWrapper

        at android.view.MenuInflater$InflatedOnMenuItemClickListener.<init>   (MenuInflater.java:202)
        at android.view.MenuInflater$MenuState.setItem(MenuInflater.java:402)
        at android.view.MenuInflater$MenuState.addItem(MenuInflater.java:436)
        at android.view.MenuInflater.parseMenu(MenuInflater.java:173)
        at android.view.MenuInflater.parseMenu(MenuInflater.java:151)
        at android.view.MenuInflater.inflate(MenuInflater.java:95)
        at 
        it.mobile.activity.home.HomeActivity.onCreateOptionsMenu(HomeActivity.java:38)
        at android.app.Activity.onCreatePanelMenu(Activity.java:2444)
        at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:388)
        at com.android.internal.policy.impl.PhoneWindow.invalidatePanelMenu(PhoneWindow.java:739)
        at com.android.internal.policy.impl.PhoneWindow$1.run(PhoneWindow.java:2833)
        at android.os.Handler.handleCallback(Handler.java:605)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4424)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at    com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
        at dalvik.system.NativeStart.main(Native Method)

 Caused by: java.lang.NoSuchMethodException: aboutDialog 
 [interface android.view.MenuItem]
        at java.lang.Class.getConstructorOrMethod(Class.java:460)
        at java.lang.Class.getMethod(Class.java:915)
        at android.view.MenuInflater$InflatedOnMenuItemClickListener.<init>  

But I don't understand where is the problem. With another device all works fine!

Foi útil?

Solução

Not sure how to solve it with just xml. From code perspective you will have to implement
public boolean onOptionsItemSelected(MenuItem item) and then depending on the menu item call the required handler.

Outras dicas

Although this is out of date, here is the reason for the exception. When you look into the sources of android API 15 (4.0.3-4.0.4) in the class MenuInflator you will see this method:

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

This is were the exception happens. As we see the method tries to find the Callback method on the class of the context item passed. So instead of calling getMenuInflator() in onCreateOptionsMenu you should call new MenuInflator(this), so that this is passed as a context and then the code will work.

Another bug fix was to remove the theme from the manifest and i am still very puzzeled why that works. But well, it's just a workaround.

I was having similar issues and I found this here -https://code.google.com/p/android/issues/detail?id=62795

    This is affecting Android 5.0 when applying the android:theme attribute.


        <Button
            android:theme="@android:style/Theme.Material"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="onLoginEmail"

Clicking on the button throws
    java.lang.IllegalStateException: Could not find a method onLoginEmail(View) in the activity class android.view.ContextThemeWrapper for onClick handler on view class android.widget.Button
            at android.view.View$1.onClick(View.java:3994)
            at android.view.View.performClick(View.java:4756)
            at android.view.View$PerformClick.run(View.java:19749)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: java.lang.NoSuchMethodException: onLoginEmail [class android.view.View]
            at java.lang.Class.getMethod(Class.java:664)
            at java.lang.Class.getMethod(Class.java:643)
            at android.view.View$1.onClick(View.java:3987)
            at android.view.View.performClick(View.java:4756)
            at android.view.View$PerformClick.run(View.java:19749)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
            />

I got around it by removing android:theme from the TextView

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top