android:onClick不适用于Android 4.0.3

时间:2014-01-30 13:31:42

标签: android menuitem

我在Android API 15的简单视图中遇到了一个奇怪的问题。在这个视图中,我有一个包含2个菜单项的简单菜单。 此代码适用于其他Android API,但不适用于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>

这是活动

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

这段代码没什么奇怪的。但是当我尝试在设备上运行时,我有这个例外:

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>  

但我不明白问题出在哪里。使用另一台设备一切正常!

3 个答案:

答案 0 :(得分:3)

不确定如何用xml解决它。 从代码角度来看,您必须实现
     public boolean onOptionsItemSelected(MenuItem item)  然后根据菜单项调用所需的处理程序。

答案 1 :(得分:3)

虽然这已经过时了,但这是例外的原因。当您在类MenuInflator中查看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;
}

这是例外情况。正如我们所看到的,该方法试图在传递的上下文项的类上找到Callback方法。因此,不应在getMenuInflator()中调用onCreateOptionsMenu,而应调用new MenuInflator(this),以便this作为上下文传递,然后代码就可以运行。

另一个错误修复是从清单中删除主题,我仍然非常困惑为什么这样做。但是,这只是一种解决方法。

答案 2 :(得分:0)

我遇到了类似的问题,我在这里找到了这个问题 - 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)
            />

我从android:theme

中移除了TextView,解决了这个问题