Android Fragment null 对象 mNextAnim 内部崩溃

Posted

技术标签:

【中文标题】Android Fragment null 对象 mNextAnim 内部崩溃【英文标题】:Android Fragment null object mNextAnim Internal Crash 【发布时间】:2015-10-02 04:32:03 【问题描述】:

我正在开发的应用程序的用户遇到了崩溃问题。这是我从控制台获得的堆栈跟踪。

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)

崩溃只发生在拥有 Galaxy Note3 或 Galaxy S4 5.x 手机的用户身上,或者至少是我们唯一得到报告但发生很多的用户。它似乎发生在片段之间的过渡或有时从相机返回时。这是我的过渡方法。

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();

这些是在应用中进行转换的唯一方法。所以我假设它来自其中之一。但是堆栈跟踪不会回到我编写的任何代码,所以我不确定。我发现了类似的问题,说这是一个 Android 5.x 问题并且没有修复。所以解决这个问题的任何帮助都会很棒

【问题讨论】:

你试过用 commit() 替换 commitAllowingStateLoss() 吗? 不,我没试过,我可以尝试替换它,看看会发生什么。 修复了它但导致旧设备崩溃和其他问题的问题 【参考方案1】:

这是因为您正在使用 null 值调用 remove() add() 等方法。 并且请记住replace() = remove()->add() 一个一个。

【讨论】:

【参考方案2】:

尝试使用扩展android.support.v4.app.Fragment 的片段而不是android.app.Fragment 并使用android.app.FragmentTransaction 而不是android.support.v4.app.FragmentTransaction

这个问题已经解决了这个问题:

Trying to remove fragment from view gives me NullPointerException on mNextAnim

试试看。

【讨论】:

以上是关于Android Fragment null 对象 mNextAnim 内部崩溃的主要内容,如果未能解决你的问题,请参考以下文章

android - Fragment getView() 总是返回null

Android getParentFragment() 在 Fragment 内的 ViewPager 中返回 null

Android getSupportFragmentManager Fragment中的NULL指针异常

Android使用Fragment,不能得到Fragment内部控件,findViewById()结果是Null--已经解决

android fragment addToBackStack(null):如何将同一个片段添加到堆栈中一次?

Android Fragment中调用getActivity为null的问题