Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Fragment null object mNextAnim Internal Crash

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

like image 802
sethprogrammer Avatar asked Jul 13 '15 19:07

sethprogrammer


2 Answers

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.

like image 169
GreenROBO Avatar answered Nov 02 '22 15:11

GreenROBO


Try to use Fragments extending android.support.v4.app.Fragment instead of android.app.Fragment and use the android.app.FragmentTransaction instead of android.support.v4.app.FragmentTransaction

This bug already solved in this question:

Trying to remove fragment from view gives me NullPointerException on mNextAnim

Try it out.

like image 42
ArtKorchagin Avatar answered Nov 02 '22 13:11

ArtKorchagin