0

I have an error I am having trouble reproducing. I think it comes about when the app is being used then the user switches aps and of goes to the homescreen for awhile then comes back to my app. The full error is:

android.view.InflateException: Couldn't resolve menu item onClick handler 
    goToSearch 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.inflate(MenuInflater.java:95)
       at com.beerportfolio.beerportfoliopro.MainDrawer2.onCreateOptionsMenu(MainDrawer2.java:172)
       at android.app.Activity.onCreatePanelMenu(Activity.java:2513)
       at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:224)
       at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:415)
       at com.android.internal.policy.impl.PhoneWindow.invalidatePanelMenu(PhoneWindow.java:770)
       at com.android.internal.policy.impl.PhoneWindow$1.run(PhoneWindow.java:3179)
       at android.os.Handler.handleCallback(Handler.java:608)
       at android.os.Handler.dispatchMessage(Handler.java:92)
       at android.os.Looper.loop(Looper.java:156)
       at android.app.ActivityThread.main(ActivityThread.java:5060)
       at java.lang.reflect.Method.invokeNative(Method.java)
       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(NativeStart.java)

Caused by: java.lang.NoSuchMethodException: 
    goToSearch [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>(MenuInflater.java:200)
       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.inflate(MenuInflater.java:95)
       at com.beerportfolio.beerportfoliopro.MainDrawer2.onCreateOptionsMenu(MainDrawer2.java:172)
       at android.app.Activity.onCreatePanelMenu(Activity.java:2513)
       at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:224)
       at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:415)
       at com.android.internal.policy.impl.PhoneWindow.invalidatePanelMenu(PhoneWindow.java:770)
       at com.android.internal.policy.impl.PhoneWindow$1.run(PhoneWindow.java:3179)
       at android.os.Handler.handleCallback(Handler.java:608)
       at android.os.Handler.dispatchMessage(Handler.java:92)
       at android.os.Looper.loop(Looper.java:156)
       at android.app.ActivityThread.main(ActivityThread.java:5060)
       at java.lang.reflect.Method.invokeNative(Method.java)
       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(NativeStart.java)

My main drawer2 class looks like this:

public class MainDrawer2 extends FragmentActivity
{
    private static final String EXTRA_NAV_ITEM    = "extraNavItem";
    private static final String STATE_CURRENT_NAV = "stateCurrentNav";

    private ActionBarDrawerToggle mDrawerToggle;
    private DrawerLayout mDrawerLayout;

    private NavDrawerListAdapter mDrawerAdapter;
    private ListView mDrawerList;

    private CharSequence mTitle;
    private CharSequence mDrawerTitle;

    private MainNavItem mCurrentNavItem;


    public static Intent createLaunchFragmentIntent(
        Context context, MainNavItem navItem)
    {
        return new Intent(context, MainDrawer2.class)
                .putExtra(EXTRA_NAV_ITEM, navItem.ordinal());
    }

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_main);
        Crashlytics.start(this);
        mTitle = mDrawerTitle = getTitle();
        mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
        mDrawerList   = (ListView)findViewById(R.id.drawer);

        getActionBar().setDisplayHomeAsUpEnabled(true);
        enableHomeButtonIfRequired();

        mDrawerAdapter = new NavDrawerListAdapter(getApplicationContext());
        mDrawerList.setAdapter(mDrawerAdapter);
        mDrawerList.setOnItemClickListener(new ListView.OnItemClickListener()
        {
            @Override
            public void onItemClick(AdapterView<?> parent, 
                View view, int position, long id)
            {
                displayNavFragment((MainNavItem)parent
                   .getItemAtPosition(position));
            }
        });

        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                R.drawable.ic_drawer, R.string.app_name, R.string.app_name)
        {
            public void onDrawerClosed(View view)
            {
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu();
            }

            public void onDrawerOpened(View drawerView)
            {
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu();
            }
        };

        mDrawerLayout.setDrawerListener(mDrawerToggle);

        if(getIntent().hasExtra(EXTRA_NAV_ITEM)){
            MainNavItem navItem = MainNavItem.values()
                    [getIntent().getIntExtra(EXTRA_NAV_ITEM,
                    MainNavItem.STATISTICS.ordinal())];
            displayNavFragment(navItem);
        }
        else if(savedInstanceState != null){
            mCurrentNavItem = MainNavItem.values()
                    [savedInstanceState.getInt(STATE_CURRENT_NAV)];
            setCurrentNavItem(mCurrentNavItem);
        }
        else{
            displayNavFragment(MainNavItem.STATISTICS);
        }
    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    private void enableHomeButtonIfRequired()
    {
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH){
            getActionBar().setHomeButtonEnabled(true);
        }
    }
    public void setActionBarTitle(String title) {
        getActionBar().setTitle(title);
    }

    @Override
    public void setTitle(CharSequence title)
    {
        mTitle = title;
        getActionBar().setTitle(mTitle);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState)
    {
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig)
    {
        super.onConfigurationChanged(newConfig);
        // Pass any configuration change to the drawer toggles
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState)
    {
        super.onSaveInstanceState(outState);

        if (mCurrentNavItem == null) {

        }
        else{
            outState.putInt(STATE_CURRENT_NAV, mCurrentNavItem.ordinal());
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    /*
    @Override
    public boolean onPrepareOptionsMenu(Menu menu)
    {
        // if nav drawer is opened, hide the action items
        boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
        menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
        return super.onPrepareOptionsMenu(menu);
    }
    */

    private void displayNavFragment(MainNavItem navItem)
    {
        //if(navItem == mCurrentNavItem) {
          //  return;
        //}
        Fragment fragment = Fragment.instantiate(this,
                navItem.getFragClass().getName());
        if(fragment != null) {
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.main, fragment)
                    .commit();
            setCurrentNavItem(navItem);
        }
    }

    private void setCurrentNavItem(MainNavItem navItem)
    {
        int position = navItem.ordinal();
        // If navItem is in DrawerAdapter
        if(position >= 0 && position < mDrawerAdapter.getCount()){
            //mDrawerList.setItemChecked(position, true);
        }
        else {
            // navItem not in DrawerAdapter, de-select current item
            if(mCurrentNavItem != null){
                //mDrawerList.setItemChecked(mCurrentNavItem.ordinal(), false);
            }
        }

        //test to keep item not selected
        int toClear=mDrawerList.getCheckedItemPosition();

        if (toClear >= 0) {
            mDrawerList.setItemChecked(toClear, false);
        }

        mDrawerLayout.closeDrawer(mDrawerList);
        setTitle(navItem.getTitleResId());
        mCurrentNavItem = navItem;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                if(mDrawerLayout.isDrawerOpen(mDrawerList)) {
                    mDrawerLayout.closeDrawer(mDrawerList);
                }
                else {
                    mDrawerLayout.openDrawer(mDrawerList);
                }
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    public void goToSearch(MenuItem item) {
        //go to search page
        Fragment Fragment_one;
        FragmentManager man= getSupportFragmentManager();
        FragmentTransaction tran = man.beginTransaction();
        Fragment_one = new Search();

        tran.replace(R.id.main, Fragment_one);//tran.
        tran.addToBackStack(null);
        tran.commit();

    }

    public void scanBarcode(MenuItem item) {
        //open scanner
        IntentIntegrator scanIntegrator = new IntentIntegrator(this);
        scanIntegrator.initiateScan();
    }

    public void onActivityResult(int requestCode, 
        int resultCode, Intent intent) {
        //retrieve scan result
        IntentResult scanningResult = IntentIntegrator
            .parseActivityResult(requestCode, resultCode, intent);
        if (scanningResult != null) {
            //we have a result

            String scanContent = scanningResult.getContents();

            //todo: set scan content into setting, 
            //load new fragment which calls async task below. New
            //todo: fragment will have same ui as search. :-)
            Fragment Fragment_one;
            FragmentManager man= this.getSupportFragmentManager();
            FragmentTransaction tran = man.beginTransaction();
            Fragment_one = new BarcodeFrag(scanContent);
            tran.replace(R.id.main, Fragment_one);//tran.
            tran.addToBackStack(null);
            //tran.commit();
            tran.commitAllowingStateLoss();
        }    
        else {
            Toast toast = Toast.makeText(getApplicationContext(),
                    "No scan data received!", Toast.LENGTH_SHORT);
            toast.show();
        }
    }


}

Lastly my menu xml looks like this:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity" >

    <item android:id="@+id/menu_search2"
        android:actionViewClass="android.widget.SearchView"
        android:title="Search"
        android:icon="@android:drawable/ic_menu_search"
        android:showAsAction="always|collapseActionView"
        android:onClick="goToSearch" />

    <item android:id="@+id/action_scan"
        android:icon="@drawable/barcode"
        android:onClick="scanBarcode"
        android:showAsAction="ifRoom|collapseActionView"/>
</menu>

I cannot for the life of me figure out where this error is coming from.

JJD
  • 50,076
  • 60
  • 203
  • 339
Mike
  • 6,751
  • 23
  • 75
  • 132

3 Answers3

2

I would recommend using the onOptionsItemSelected mechanism if possible instead of manually wiring the click methods.

Take a look at the documentation: Android Developer Guide:Menus

Matt T
  • 29
  • 1
  • I changed both my files to this: https://gist.github.com/anonymous/83b24469a0f8cdeaf52b And now it force closes for me every time I open it – Mike May 21 '14 at 23:08
0

You might have found a platform bug. Does it still happen if you set your activity theme to Theme.Holo or Theme.Holo.Light? Specifically, try it with something that isn't based on Theme.Holo.Light.DarkActionBar.

If this fixes your original problem please report this at http://b.android.com.

adamp
  • 28,862
  • 9
  • 81
  • 69
0

You have wrong method signature.

This is yours

public void goToSearch(MenuItem item){
}

This is how it should be

public void goToSearch(View v){ 
}

please see http://developer.android.com/reference/android/R.attr.html#onClick for reference

KSI
  • 353
  • 2
  • 9