为什么MainActivity的所有实例变量在onNavigationDrawerItemSelected方法中都是null,NavigationDrawer + Viewpager

Why all instance variables of MainActivity are all null inside onNavigationDrawerItemSelected method, NavigationDrawer + Viewpager

我的申请需要 NagivationDrawerViewPager。当用户 select 抽屉中的项目时,视图分页器将相应地设置片段。并且用户还可以在页面(片段)之间滑动。

我的代码如下

public class MainActivity extends AppCompatActivity
        implements NavigationDrawerFragment.NavigationDrawerCallbacks {

    private NavigationDrawerFragment mNavigationDrawerFragment;  
    private CharSequence mTitle;
    private ViewPager mViewPager;
    private LessonPageAdapter lessonPageAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        mNavigationDrawerFragment = (NavigationDrawerFragment)
                getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
        mTitle = getTitle();

        // Set up the drawer.
        mNavigationDrawerFragment.setUp(
                R.id.navigation_drawer,
                (DrawerLayout) findViewById(R.id.drawer_layout));

        lessonPageAdapter = new LessonPageAdapter(getSupportFragmentManager());

        this.mViewPager = (ViewPager) findViewById(R.id.pager);
        this.mViewPager.setAdapter(lessonPageAdapter);

    }

    @Override
    public void onNavigationDrawerItemSelected(int position) {

        Bundle args = new Bundle();
        args.putInt(LessonFragment.ARG_SECTION_NUMBER, position + 1);


        //this causes null pointer exception
        mViewPager.setCurrentItem(position + 1);


    }
........ 

但是onNavigationDrawerItemSelected函数中的mViewPager.setCurrentItem(position + 1)导致了空指针异常(如下图),我发现MainActivity的所有实例变量在[=15=里面都是null ] 方法。

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.khaino.drawerandswipedemo/com.example.khaino.drawerandswipedemo.MainActivity}: android.view.InflateException: Binary XML file line #29: Error inflating class fragment
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
            at android.app.ActivityThread.access0(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            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:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
     Caused by: android.view.InflateException: Binary XML file line #29: Error inflating class fragment
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:763)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
            at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:255)
            at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109)
            at com.example.khaino.drawerandswipedemo.MainActivity.onCreate(MainActivity.java:37)
            at android.app.Activity.performCreate(Activity.java:5990)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
            at android.app.ActivityThread.access0(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            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:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.view.ViewPager.setCurrentItem(int)' on a null object reference
            at com.example.khaino.drawerandswipedemo.MainActivity.onNavigationDrawerItemSelected(MainActivity.java:66)
            at com.example.khaino.drawerandswipedemo.NavigationDrawerFragment.selectItem(NavigationDrawerFragment.java:210)
            at com.example.khaino.drawerandswipedemo.NavigationDrawerFragment.onCreate(NavigationDrawerFragment.java:81)
            at android.support.v4.app.Fragment.performCreate(Fragment.java:1939)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:988)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1185)
            at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1287)
            at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2243)
            at android.support.v4.app.FragmentController.onCreateView(FragmentController.java:111)
            at android.support.v4.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:278)
            at android.support.v4.app.BaseFragmentActivityHoneycomb.onCreateView(BaseFragmentActivityHoneycomb.java:31)
            at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:78)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
            at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:255)
            at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109)
            at com.example.khaino.drawerandswipedemo.MainActivity.onCreate(MainActivity.java:37)
            at android.app.Activity.performCreate(Activity.java:5990)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
            at android.app.ActivityThread.access0(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            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:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

任何人都可以告诉我原因以及满足我的应用程序要求的解决方案。

堆栈跟踪显示,在设置 mViewPager 字段之前从 onCreate 间接调用了该方法。

setContentView 调用之后直接移动字段赋值应该可以解决该问题:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    this.mViewPager = (ViewPager) findViewById(R.id.pager);
    lessonPageAdapter = new LessonPageAdapter(getSupportFragmentManager());
    this.mViewPager.setAdapter(lessonPageAdapter);

    mNavigationDrawerFragment = (NavigationDrawerFragment)
            getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
    mTitle = getTitle();

    // Set up the drawer.
    mNavigationDrawerFragment.setUp(
            R.id.navigation_drawer,
            (DrawerLayout) findViewById(R.id.drawer_layout));

}

当我打印执行步骤时,它显示 onCreate 方法 mViewPager 被初始化,然后 onNavigationDrawerItemSelected 被调用,如下所示

11-01 11:47:07.056  15082-15082/? D/step﹕ onCreate
11-01 11:47:07.153  15082-15082/? D/step﹕ onNavigationDrawerItemSelected

为了避免空指针异常,当我运行 应用程序时,我检查 mViewPager 是否不为 null,如下所示,它工作正常

   @Override
   public void onNavigationDrawerItemSelected(int position) {

        Bundle args = new Bundle();
        args.putInt(LessonFragment.ARG_SECTION_NUMBER, position + 1);

        Log.d("step", "onNavigationDrawerItemSelected");

       //to void null pointer exception when I run the app       
       if(mViewPager != null){
           mViewPager.setCurrentItem(position + 1);
       }
  }