NullPointerException in FragmentManager

2019-01-22 02:57发布

问题:

I'm using the Android compatibility library and occasionally get a weird NullPointerException:

java.lang.NullPointerException
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:960)
    at android.support.v4.app.FragmentManagerImpl.performPendingDeferredStart(FragmentManager.java:768)
    at android.support.v4.app.FragmentManagerImpl.startPendingDeferredFragments(FragmentManager.java:1104)
    at android.support.v4.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:410)
    at android.support.v4.content.Loader.deliverResult(Loader.java:103)
    at android.support.v4.content.CursorLoader.deliverResult(CursorLoader.java:81)
    at android.support.v4.content.CursorLoader.onStartLoading(CursorLoader.java:126)
    at android.support.v4.content.Loader.startLoading(Loader.java:197)
    at android.support.v4.app.LoaderManagerImpl$LoaderInfo.start(LoaderManager.java:262)
    at android.support.v4.app.LoaderManagerImpl.doStart(LoaderManager.java:710)
    at android.support.v4.app.Fragment.onStart(Fragment.java:981)
    at android.support.v4.app.Fragment.performStart(Fragment.java:1332)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:906)
    at android.support.v4.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1240)
    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:612)
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1416)
    at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:431)
    at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:139)
    at android.support.v4.view.ViewPager.populate(ViewPager.java:804)
    at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:433)
    at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:405)
    at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:386)
    ...

Obviously, I'm doing something wrong to allow the FragmentManager to get into such a state where it can crash like this, but I have no clue what. The relevant code in the FragmentManagerImpl is not offering me any clues. I'm guessing mActivity is somehow null at that point in the code? But that seems impossible as the activity is already on the screen and I'm not adding any fragments to it — just switching among them in a ViewPager.

回答1:

Ok guys, after hitting my head against a brick wall for a while on this I found that this was directly associated with my fragment's declaration of setRetainInstance(true). After removing this the problems went away. This appears to be a compatibility library bug...

I will raise something under the appropriate Google project. Best of luck if you are reading this slowly sobbering to yourself! I hope this will allow you to work around the problem.



回答2:

I got this error a few days ago and was quite confounded, but I figured out that it was because a FragmentTransaction didn't seem to get any pending transactions so when calling executePendingTransactions(); A NPE much like this one was thrown.
I solved it by making sure that every transaction actually changed something (i.e add fragment 1 -> remove fragment 1 -> commit/execute would not work).
Also make sure that none of the fragments in the pager have become null.



回答3:

I was getting the same error because I was referencing an instance of a fragment in a view pager adapter rather that the fragment itself.

Creating a new instance of the fragment each time the fragment was called resolved this error. Obviously this is proper programming but just in case some other noobs are making that mistake....

@Override
public Fragment getItem(int position) {
    if(position == 0)
        return new Walkthrough_Fragment_1();
    if(position == 1)
        return new Walkthrough_Fragment_4();
    if(position == 2)
        return new Walkthrough_Fragment_2();
    else{
        return new  Walkthrough_Fragment_3();
    }
}


回答4:

This bug occurs when using FragmentPagerAdapter inside a Fragment that use setRetainInstance(true).

If you want to maintain the setRetainInstance(true) you can use @Marc answer from This question:

@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
    //do nothing here! no call to super.restoreState(arg0, arg1);
}


回答5:

At some point You are using instance of FragmentManager class, which is not initialized. Find that point and initialize object properly.



回答6:

I just read that you can not perform certain transactions on Fragments that were added at compile time. For example, if your Fragment was defined in XML and you try to replace it, boom.



回答7:

I solved my issue by making my FragmentManager as a static global variable, then initialized it in your onCreate method. I found out that using getSupportFragmentManager() everywhere in your code can result this exception, because getSupportFragmentManager() may point to your older fragment manager value and may not be referenced.

Here is a example:

  public class yourClass{

      private static FragmentManager myFragmentManagerSupport; 
      ...

        @Override
        public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
          myFragmentManagerSupport = this.getSupportFragmentManager();

              ....

          }

         /*Then reuse myFragmentManagerSupport  everywhere you needed instead of  
         *                     getSupportFragmentManager()
         */

    }

Hope it help.