Android Fragment null object mNextAnim Internal Crash

sethprogrammer picture sethprogrammer · Jul 13, 2015 · Viewed 15.8k times · Source

Users of the app I am working on have a crashing issue. This is the stack trace I get from the console.

java.lang.NullPointerException: Attempt to write to field 'int android.support.v4.app.Fragment.mNextAnim' on a null object reference
at android.support.v4.app.BackStackRecord.popFromBackStack(BackStackRecord.java:924)
at android.support.v4.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1605)
at android.support.v4.app.FragmentManagerImpl$4.run(FragmentManager.java:532)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:458)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5942)
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:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)

The crash only happens with users that have Galaxy Note3 or Galaxy S4 phones with 5.x or at least those our the only one that have got reported but it has happen a lot. It seems to happen on transition between fragments or sometimes when coming back from the camera. Here are my transition methods.

public void popBackStackToOr(String popBackFragmentName, String secondPopBackFragment)
{
    int backStackId = 0;
    int backStackCount = getSupportFragmentManager().getBackStackEntryCount();

    List<Fragment> fragments = getSupportFragmentManager().getFragments();

    for (int k = (backStackCount - 1); k > 0; k--)
    {
        String aFragmentClass = fragments.get(k).getClass().toString();
        String[] splitList = aFragmentClass.split("\\.");
        aFragmentClass = splitList[splitList.length - 1];

        boolean firstOptionTrue  = aFragmentClass.equalsIgnoreCase(popBackFragmentName);
        boolean secondOptionTrue = aFragmentClass.equalsIgnoreCase(secondPopBackFragment);

        if ( (firstOptionTrue) || (secondOptionTrue) )
        {
            backStackId = getSupportFragmentManager().getBackStackEntryAt(k).getId();
            break;
        }
    }

    getSupportFragmentManager().popBackStack(backStackId, android.support.v4.app.FragmentManager.POP_BACK_STACK_INCLUSIVE); //Immediate
}

public void popBackStackForReview(String popBackFragmentName)
{
    int backStackId = 0;
    int backStackCount = getSupportFragmentManager().getBackStackEntryCount();

    List<Fragment> fragments = getSupportFragmentManager().getFragments();

    for (int k = (backStackCount - 1); k > 0; k--)
    {
        String aFragmentClass = fragments.get(k).getClass().toString();
        String[] splitList = aFragmentClass.split("\\.");
        aFragmentClass = splitList[splitList.length - 1];
        if (aFragmentClass.equalsIgnoreCase(popBackFragmentName))
        {
            backStackId = getSupportFragmentManager().getBackStackEntryAt(k).getId();
            break;
        }
    }

    getSupportFragmentManager().popBackStack(backStackId, android.support.v4.app.FragmentManager.POP_BACK_STACK_INCLUSIVE);
}

public void transitionToLoginPage()
{
    Fragment newFragment = new LoginPage();

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

    transaction.replace(R.id.frame_container, newFragment);
    //transaction.addToBackStack(null);

    transaction.commitAllowingStateLoss();
}

public void transitionToNewScreen(Fragment newFragment, Bundle bundle)
{
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

    if (currentFragment != null)
    {
        transaction.remove(currentFragment);
    }

    currentFragment = newFragment;

    if (bundle != null)
    {
        newFragment.setArguments(bundle);
    }

    transaction.replace(R.id.frame_container, newFragment);
    transaction.addToBackStack("dummy");

    transaction.commitAllowingStateLoss();
}

public void transitionToNewScreenAndEmptyStack(Fragment newFragment)
{
    getSupportFragmentManager().popBackStack(0, android.support.v4.app.FragmentManager.POP_BACK_STACK_INCLUSIVE);

    currentFragment = newFragment;

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.frame_container, newFragment);
    transaction.addToBackStack(null);
    transaction.commitAllowingStateLoss();
}

These are the only methods that do transition in the app. So I am assuming it is coming from one of these. But the stack trace does not go back to any code I wrote so I am not sure. I have found similar problems saying that this is a Android 5.x issue and there was no fix. So any help to remove this issue would be great

Answer

GreenROBO picture GreenROBO · Oct 28, 2015

It's because you are calling remove() add() etc. methods with null value.

and please keep in mind that replace() = remove()->add() one by one.