从Fragment setUserVisibleHint调用时,getActivity返回Null Pointer Exception

时间:2017-12-04 06:15:55

标签: android android-fragments

我有一个主要活动的应用程序调用3个片段。我在从第一个片段访问getActivity的阶段看到应用程序启动时出现空指针异常。

 E/AndroidRuntime: FATAL EXCEPTION: main Process: com.inc.sr, PID: 3019
 java.lang.NullPointerException: Attempt to invoke virtual method
 'android.support.v7.app.ActionBar
 com.inc.sr.MainActivity.getSupportActionBar()' on a null object
 reference
     at com.inc.sr.fragments.SRFrag.setUserVisibleHint(SRFrag.java:148)
     at android.support.v4.app.FragmentPagerAdapter.setPrimaryItem(FragmentPagerAdapter.java:136)
     at android.support.v4.view.ViewPager.populate(ViewPager.java:1234)
     at android.support.v4.view.ViewPager.populate(ViewPager.java:1084)   
     at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1614)
     at android.view.View.measure(View.java:18788)
     at android.widget.LinearLayout.measureVertical(LinearLayout.java:901)
     at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
     at android.view.View.measure(View.java:18788)
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
     at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
     at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
     at android.view.View.measure(View.java:18788) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
     at android.widget.LinearLayout.measureVertical(LinearLayout.java:748) 
     at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)      
     at android.view.View.measure(View.java:18788)
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
     at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
     at android.view.View.measure(View.java:18788)
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
     at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
     at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
     at android.view.View.measure(View.java:18788)
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
     at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
     at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2643)
     at android.view.View.measure(View.java:18788)
     at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2100)
     at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1216)
     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1452)
     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
     at android.view.Choreographer.doCallbacks(Choreographer.java:670)
     at android.view.Choreographer.doFrame(Choreographer.java:606)
     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
     at android.os.Handler.handleCallback(Handler.java:739)
     at android.os.Handler.dispatchMessage(Handler.java:95)
     at android.os.Looper.loop(Looper.java:148)
     at android.app.ActivityThread.main(ActivityThread.java:5417)
     at java.lang.reflect.Method.invoke(Native Method)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 12-04
 13:25:33.229 1261-2076/? E/SurfaceFlinger: ro.sf.lcd_density must be
 defined as a build property 12-04 13:25:33.237 3019-3042/com.inc.sr
 E/FA: Failed to send current screen to service 12-04 13:25:33.237
 3019-3042/com.inc.sr E/FA: Discarding data. Failed to send event to
 service 12-04 13:25:33.238 3019-3042/com.inc.sr E/FA: Failed to send
 current screen to service 12-04 13:26:22.703
 2452-2870/com.google.android.gms E/SQLiteCastStore: End saving paired
 guest mode devices 12-04 13:30:33.228 1634-3092/system_process
 E/Surface: getSlotFromBufferLocked: unknown buffer: 0xb40be100 12-04
 13:30:33.239 1634-1645/system_process E/JavaBinder: !!! FAILED BINDER
 TRANSACTION !!!  (parcel size = 104) 12-04 13:30:33.244
 1634-1645/system_process E/JavaBinder: !!! FAILED BINDER TRANSACTION
 !!!  (parcel size = 104)

主要活动

public class MainActivity extends AppCompatActivity {

private Toolbar toolbar;
private TabLayout tabLayout;
private CustomViewPager viewPager;
private MyAdapter mAdapter;
TextView mTitle;
String[] title = {"S screen", "Compare", "About US"};
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //FirebaseDatabase.getInstance().setPersistenceEnabled(true);

    if (findViewById(R.id.fragment_container) != null) {
        if (savedInstanceState != null) {
            return;
        }

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        getSupportActionBar().setDisplayHomeAsUpEnabled(false);
        //getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setDisplayShowTitleEnabled(false);
        mTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);
        mTitle.setText(title[0]);

        mAdapter = new MyAdapter(getSupportFragmentManager());
        //viewPager = (ViewPager)findViewById(R.id.viewpager);
        viewPager = (CustomViewPager) findViewById(R.id.viewpager);
        viewPager.setAdapter(mAdapter);
        viewPager.setPagingEnabled(false);

        tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(viewPager);

        tabLayout.getTabAt(0).setIcon(R.mipmap.searchs);
        tabLayout.getTabAt(1).setIcon(R.mipmap.compareu);
        tabLayout.getTabAt(2).setIcon(R.mipmap.infou);

        tabLayout.setOnTabSelectedListener(
                new TabLayout.ViewPagerOnTabSelectedListener(viewPager) {

                    @Override
                    public void onTabSelected(TabLayout.Tab tab) {
                        super.onTabSelected(tab);
                        int pos = tab.getPosition();

                        switch (pos) {
                            case 0:
                                tabLayout.getTabAt(0).setIcon(R.mipmap.searchs);
                                break;
                            case 1:
                                tabLayout.getTabAt(1).setIcon(R.mipmap.compares);
                                break;
                            case 2:
                                tabLayout.getTabAt(2).setIcon(R.mipmap.infos);
                                break;
                        }
                    }

                    @Override
                    public void onTabUnselected(TabLayout.Tab tab) {
                        super.onTabUnselected(tab);
                        int pos = tab.getPosition();
                        switch (pos) {
                            case 0:
                                tabLayout.getTabAt(0).setIcon(R.mipmap.searchu);
                                break;
                            case 1:
                                tabLayout.getTabAt(1).setIcon(R.mipmap.compareu);
                                break;
                            case 2:
                                tabLayout.getTabAt(2).setIcon(R.mipmap.infou);
                                break;
                        }
                    }

                    @Override
                    public void onTabReselected(TabLayout.Tab tab) {
                        super.onTabReselected(tab);
                    }
                }
        );

        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {

                FragmentManager fragmentManager = MainActivity.this.getSupportFragmentManager();
                List<Fragment> fragments = fragmentManager.getFragments();
                if (fragments != null) {
                    for (Fragment fragment : fragments) {
                        if (fragment != null && fragment.isVisible()) {

                            switch (position) {
                                case 0:
                                    if (fragment.getClass().toString().contains("srFrag")) {
                                        getSupportActionBar().setDisplayHomeAsUpEnabled(false);
                                        mTitle.setText(title[position]);
                                    } else if (fragment.getClass().toString().contains("sresFrag")) {
                                        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
                                        String state = fragment.getArguments().getString("STATES", "");
                                        String grade = fragment.getArguments().getString("GRADES", "");
                                        String title = state + " - " + grade + " Ranking";
                                        mTitle.setText(title);
                                    } else if (fragment.getClass().toString().contains("sdFrag")) {
                                        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
                                        String title = fragment.getArguments().getString("SCNAME", "");
                                        mTitle.setText(title);
                                    }
                                    break;
                                case 1:
                                    if (fragment.getClass().toString().contains("CompareFrag")) {
                                        getSupportActionBar().setDisplayHomeAsUpEnabled(false);
                                        mTitle.setText(title[position]);
                                    } else if (fragment.getClass().toString().contains("CompareResultsFrag")) {
                                        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
                                        mTitle.setText("Compare Results");
                                    }
                                    break;
                                case 2:
                                    if (fragment.getClass().toString().contains("InfoFrag")) {
                                        getSupportActionBar().setDisplayHomeAsUpEnabled(false);
                                        mTitle.setText(title[position]);
                                    }
                                    break;
                            }
                        }
                    }
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

    mAuthListener = new FirebaseAuth.AuthStateListener() {
        @Override
        public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
            FirebaseUser user = firebaseAuth.getCurrentUser();
            if (user != null) {
                // User is signed in
                System.out.println("AUTH FirebaseAuth onAuthStateChanged:signed_in:" + user.getUid());
            } else {
                // User is signed out
                System.out.println("AUTH FirebaseAuth onAuthStateChanged:signed_out");
            }
        }
    };

    mAuth = FirebaseAuth.getInstance();

    mAuth.signInAnonymously()
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    System.out.println("AUTH FirebaseAuth signInAnonymously:onComplete:" + task.isSuccessful());

                    if (!task.isSuccessful()) {
                        System.out.println("AUTH FirebaseAuth signInAnonymously" + task.getException());

                    }
                }
            });

}

@Override
public void onStart() {
    super.onStart();
    mAuth.addAuthStateListener(mAuthListener);
}

@Override
public void onStop() {
    super.onStop();
    if (mAuthListener != null) {
        mAuth.removeAuthStateListener(mAuthListener);
    }
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // handle arrow click here
    if (item.getItemId() == android.R.id.home) {
        //finish(); // close this activity and return to preview activity (if there is any)
        onBackPressed();
    }

    return super.onOptionsItemSelected(item);
}

public void onBackPressed() {
    if (viewPager.getCurrentItem() == 0) {
        if (mAdapter.getItem(0) instanceof sresFrag) {
            ((sresFrag) mAdapter.getItem(0)).backPressed();
        } else if (mAdapter.getItem(0) instanceof sdFrag) {
            ((sdFrag) mAdapter.getItem(0)).backPressed();
        } else {
            this.moveTaskToBack(true);
        }
    } else if (viewPager.getCurrentItem() == 1) {
        if (mAdapter.getItem(1) instanceof CompareResultsFrag) {
            ((CompareResultsFrag) mAdapter.getItem(1)).backPressed();
        } else if (mAdapter.getItem(1) instanceof CompareFrag) {
            viewPager.setCurrentItem(0);
        }
    } else if (viewPager.getCurrentItem() == 2) {
        if (mAdapter.getItem(2) instanceof InfoFrag) {
            viewPager.setCurrentItem(1);
        }
    }
}

private static class MyAdapter extends FragmentPagerAdapter {

    private final class FirstPageListener implements
            FirstPageFragmentListener {
        public void onSwitchToNextFragment(String year, String state, String grade, SchoolItem item, boolean backPressed) {
            mFragmentManager.beginTransaction().remove(mFragmentAtPos0)
                    .commit();
            if (mFragmentAtPos0 instanceof srFrag) {
                mFragmentAtPos0 = sresFrag.createInstance(FirstListener);
                Bundle args = new Bundle();
                args.putString("YEARS", year);
                args.putString("STATES", state);
                args.putString("GRADES", grade);
                mFragmentAtPos0.setArguments(args);
            } else if (mFragmentAtPos0 instanceof sresFrag && !(backPressed)) {
                mFragmentAtPos0 = sdFrag.createInstance(FirstListener);
                Bundle args = new Bundle();
                args.putString("YEARS", year);
                args.putString("STATES", state);
                args.putString("GRADES", grade);
                args.putSerializable("ITEM", item);
                args.putString("SCNAME", item.Name);
                mFragmentAtPos0.setArguments(args);
            } else if (mFragmentAtPos0 instanceof sdFrag && (backPressed)) {
                mFragmentAtPos0 = sresFrag.createInstance(FirstListener);
                Bundle args = new Bundle();
                System.out.println(year + state + grade);
                args.putString("YEARS", year);
                args.putString("STATES", state);
                args.putString("GRADES", grade);
                mFragmentAtPos0.setArguments(args);
            } else { // Instance of NextFragment
                mFragmentAtPos0 = srFrag.createInstance(FirstListener);
                System.out.println("UNI00 A");
            }

            notifyDataSetChanged();
        }
    }

    private final class SecondPageListener implements
            SecondPageFragmentListener {
        public void onSwitchToNextFragment(ArrayList<SchoolItem> schoolList, SchoolItem[] compareList, boolean backPressed) {
            mFragmentManager.beginTransaction().remove(mFragmentAtPos1)
                    .commit();
            if (mFragmentAtPos1 instanceof CompareFrag) {
                mFragmentAtPos1 = CompareResultsFrag.createInstance(SecondListener);
            } else { // Instance of NextFragment
                mFragmentAtPos1 = CompareFrag.createInstance(SecondListener);
            }

            Bundle args = new Bundle();
            args.putSerializable("SCLIST", schoolList);
            args.putSerializable("CMLIST", compareList);
            mFragmentAtPos1.setArguments(args);

            notifyDataSetChanged();
        }
    }

    private final class ThirdPageListener implements
            ThirdPageFragmentListener {
        public void onSwitchToNextFragment() {
            mFragmentManager.beginTransaction().remove(mFragmentAtPos2)
                    .commit();
            mFragmentAtPos2 = InfoFrag.createInstance(ThirdListener);

            notifyDataSetChanged();
        }
    }


    private String[] titles = {"Search", "Compare", " Info"};
    private final FragmentManager mFragmentManager;
    public Fragment mFragmentAtPos0;
    public Fragment mFragmentAtPos1;
    public Fragment mFragmentAtPos2;
    private Context context;
    FirstPageListener FirstListener = new FirstPageListener();
    SecondPageListener SecondListener = new SecondPageListener();
    ThirdPageListener ThirdListener = new ThirdPageListener();

    public MyAdapter(FragmentManager fragmentManager) {
        super(fragmentManager);
        mFragmentManager = fragmentManager;
        System.out.println("UNI00 B");
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return titles[position];
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0: // Fragment # 0
                if (mFragmentAtPos0 == null) {
                    //mFragmentAtPos0 = new OneFragment(listener);
                    mFragmentAtPos0 = srFrag.createInstance(FirstListener);
                    System.out.println("UNI00 1");
                }
                System.out.println(mFragmentAtPos0.toString());
                return mFragmentAtPos0;
            case 1: // Fragment # 1
                if (mFragmentAtPos1 == null) {
                    //mFragmentAtPos0 = new OneFragment(listener);
                    mFragmentAtPos1 = CompareFrag.createInstance(SecondListener);
                    System.out.println("UNI00 2");
                }
                //return new BuyMainFrag();
                return mFragmentAtPos1;
            case 2:// Fragment # 2
                if (mFragmentAtPos2 == null) {
                    //mFragmentAtPos0 = new OneFragment(listener);
                    mFragmentAtPos2 = InfoFrag.createInstance(ThirdListener);
                    System.out.println("UNI00 3");
                }
                return mFragmentAtPos2;
            //return new SellMainFrag();
        }
        System.out.println("UNI00 4");
        return null;
    }

    @Override
    public int getCount() {
        return titles.length;
    }

    @Override
    public int getItemPosition(Object object) {
        if (object instanceof srFrag &&
                mFragmentAtPos0 instanceof sresFrag) {
            return POSITION_NONE;
        }
        if (object instanceof sresFrag &&
                mFragmentAtPos0 instanceof srFrag) {
            return POSITION_NONE;
        }
        if (object instanceof sresFrag &&
                mFragmentAtPos0 instanceof sdFrag) {
            return POSITION_NONE;
        }
        if (object instanceof sdFrag &&
                mFragmentAtPos0 instanceof srFrag) {
            return POSITION_NONE;
        }
        if (object instanceof CompareFrag &&
                mFragmentAtPos1 instanceof CompareResultsFrag) {
            return POSITION_NONE;
        }
        if (object instanceof CompareResultsFrag &&
                mFragmentAtPos1 instanceof CompareFrag) {
            return POSITION_NONE;
        }
        if (object instanceof InfoFrag) {
            return POSITION_NONE;
        }
        return POSITION_UNCHANGED;
    }

}

public void setToolBarTitle(String title) {
    mTitle.setText(title);
}
}

First Fragment

public class srFrag extends Fragment {

Spinner spinnerYear, spinnerState, spinnerGrade;
static FirstPageFragmentListener firstPageListener;
private String year = "", state = "", grade = "";
String FragTitle = "s screen";
private SchoolItem notUsed;

public static srFrag createInstance(FirstPageFragmentListener listener) {
    srFrag frag = new srFrag();
    firstPageListener = listener;
    return frag;
}

public srFrag() {
    // Required empty public constructor
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.s_r, container, false);      

    spinnerYear = (Spinner) view.findViewById(R.id.spinnerYear);
    ArrayAdapter<CharSequence> adapterYear = ArrayAdapter
            .createFromResource(view.getContext(), R.array.year, R.layout.spinner_row);
    spinnerYear.setAdapter(adapterYear);

    spinnerState = (Spinner) view.findViewById(R.id.spinnerState);
    ArrayAdapter<CharSequence> adapterState = ArrayAdapter
            .createFromResource(view.getContext(), R.array.state, R.layout.spinner_row);
    spinnerState.setAdapter(adapterState);

    spinnerGrade = (Spinner) view.findViewById(R.id.spinnerGrade);
    ArrayAdapter<CharSequence> adapterGrade = ArrayAdapter
            .createFromResource(view.getContext(), R.array.grade, R.layout.spinner_row);
    spinnerGrade.setAdapter(adapterGrade);        

    spinnerYear.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int pos,
                                   long arg3) {
            year = parent.getItemAtPosition(pos).toString();
            SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sharedPref.edit();
            editor.putString("YEARS", year);
            editor.commit();
        }

        @Override
        public void onNothingSelected(AdapterView<?> arg0) {
        }
    });

    spinnerState.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int pos,
                                   long arg3) {
            state = parent.getItemAtPosition(pos).toString();
            SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sharedPref.edit();
            editor.putString("STATES", state);
            editor.commit();
        }

        @Override
        public void onNothingSelected(AdapterView<?> arg0) {
        }
    });

    spinnerGrade.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int pos,
                                   long arg3) {
            grade = parent.getItemAtPosition(pos).toString();
            SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sharedPref.edit();
            editor.putString("GRADES", grade);
            editor.commit();
        }

        @Override
        public void onNothingSelected(AdapterView<?> arg0) {
        }
    });

    Button button = (Button) view.findViewById(R.id.search_button);
    button.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            firstPageListener.onSwitchToNextFragment(year, state, grade, notUsed, false);
        }
    });

    return view;
}

@Override
public void onResume() {
    super.onResume();
}

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    if (isVisibleToUser) {
        ((MainActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false); //Null pointer exception thrown here
        ((MainActivity) getActivity()).setToolBarTitle(FragTitle);

    }
}
}

3 个答案:

答案 0 :(得分:1)

如果片段未附加到Activity,则getActivity将返回null。因此,您需要检查此值是否为null或检查附加到活动的片段或onAttach()之后。

 boolean isAttached = false;
@Override
public void onAttach(Context context) {
    super.onAttach(context);
    isAttached=true;
    // save the context here if needed
}


 @Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if(getActivity()!=null){// Or use the context saved in onAttach()
        // Do your stuff
    }
}

我遇到了同样的问题,因为当getActivity()返回上下文时,setUserVisibleHint不会在第二个实例上被触发。 因此,管理是使用Listener更好的方式。使用 ViewPager.OnPageChangeListener 通知您当前的片段。

答案 1 :(得分:0)

是的,它会抛出错误,因为它会在你的布局没有被加载时调用它所以你必须等待一段时间,

这个技巧可能对你有帮助

    @Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    if (isVisibleToUser) {
new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                ((MainActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false); //Null pointer exception thrown here
        ((MainActivity) getActivity()).setToolBarTitle(FragTitle);
            }
        }, 500);

    }
}

答案 2 :(得分:0)

这样做

申报 私人活动活动;

在上面。然后写下面的函数

@Override
public void onAttach(Context context)
{
    super.onAttach(context);
    if (context instanceof Activity)
    {
        activity = (Activity) context;
    }
}

然后像这样使用

if (isVisibleToUser) {
    (activity).getSupportActionBar().setDisplayHomeAsUpEnabled(false); //Null pointer exception thrown here
    (activity).setToolBarTitle(FragTitle);

}