android:onClick doesn't work with Android 4.0.3

爷,独闯天下 提交于 2019-12-13 02:25:39

问题


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!


回答1:


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.




回答2:


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.




回答3:


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



来源:https://stackoverflow.com/questions/21457929/androidonclick-doesnt-work-with-android-4-0-3

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!