对OnPrepareOptionsMenu的调用会产生空指针异常

时间:2014-05-27 21:07:11

标签: android android-actionbar navigation-drawer

每次调用getActivity().invalidateOptionsMenu();时,由于空指针异常,我的应用程序将取消预测。

我的目标是根据我的导航抽屉中通过ListView调用的片段更改操作设置。

我的OnPrepareOptionsMenu方法如下:

public boolean onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    if (mNumber == 1) {
        menu.findItem(R.id.sortByDivision).setVisible(false);
        menu.findItem(R.id.sortByFighter).setVisible(false);
    }
    if (mNumber == 2) {
        menu.findItem(R.id.sortByDivision).setVisible(false);
        menu.findItem(R.id.sortByFighter).setVisible(true);
    }
    if (mNumber == 3) {
        menu.findItem(R.id.sortByDivision).setVisible(true);
        menu.findItem(R.id.sortByFighter).setVisible(false);
    }
    if (mNumber == 4) {
        menu.findItem(R.id.sortByDivision).setVisible(false);
        menu.findItem(R.id.sortByFighter).setVisible(false);
    }
    return true;
    //return super.onPrepareOptionsMenu(menu);
}

对此方法的调用如下:

  @Override
            public void onDrawerClosed(View drawerView) {
                super.onDrawerClosed(drawerView);
                if (!isAdded()) {
                    return;
                }

                //getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
            }

            @Override
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                if (!isAdded()) {
                    return;
                }

                if (!mUserLearnedDrawer) {
                    // The user manually opened the drawer; store this flag to prevent auto-showing
                    // the navigation drawer automatically in the future.
                    mUserLearnedDrawer = true;
                    SharedPreferences sp = PreferenceManager
                            .getDefaultSharedPreferences(getActivity());
                    sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
                }

                //getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
            }
        };

如有必要,我可以发布更多代码或整个文件。我的logcat指向第一个未注释掉的menu.findItem ...语句。

05-27 16:50:17.898  25117-25117/com.MMA E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.MMA, PID: 25117
    java.lang.NullPointerException
            at com.MMA.BMMA.onPrepareOptionsMenu(BMMA.java:129)
            at android.app.Activity.onPreparePanel(Activity.java:2564)
            at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:464)
            at com.android.internal.policy.impl.PhoneWindow.doInvalidatePanelMenu(PhoneWindow.java:800)
            at com.android.internal.policy.impl.PhoneWindow$1.run(PhoneWindow.java:221)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
            at android.view.Choreographer.doCallbacks(Choreographer.java:574)
            at android.view.Choreographer.doFrame(Choreographer.java:543)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5102)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method)

2 个答案:

答案 0 :(得分:3)

我花了一段时间,但我发现了。当未加载视图时,我正在调用更改操作栏项,这导致我调用不存在的值。我使用if语句修复了这个问题,该语句不允许我的on prepare方法做任何事情,直到视图中有值。

高效?可能不是。它有用吗? YES!

 if(menu.findItem(R.id.sortByDivision) != null && menu.findItem(R.id.sortByFighter) != null) {
            if (mNumber == 1) {
                menu.findItem(R.id.sortByDivision).setVisible(false);
                menu.findItem(R.id.sortByFighter).setVisible(false);
            }

            if (mNumber == 2) {
                menu.findItem(R.id.sortByDivision).setVisible(false);
                menu.findItem(R.id.sortByFighter).setVisible(true);
            }
            if (mNumber == 3) {

                menu.findItem(R.id.sortByDivision).setVisible(true);
                menu.findItem(R.id.sortByFighter).setVisible(false);
            }
            if (mNumber == 4) {
                menu.findItem(R.id.sortByDivision).setVisible(false);
                menu.findItem(R.id.sortByFighter).setVisible(false);
            }
        }
        return true;
        //return super.onPrepareOptionsMenu(menu);
    }

答案 1 :(得分:2)

您是否尝试过setHasOptionsMenu(true)

你给菜单充气吗?也许尝试这样getmenuinflater().inflate(r.menu.main menu)

同时仔细检查菜单项的ID。