java Android Fragment null 对象 mNextAnim 内部崩溃

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31391356/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 18:32:20  来源:igfitidea点击:

Android Fragment null object mNextAnim Internal Crash

javaandroidandroid-fragmentsandroid-studioback-stack

提问by sethprogrammer

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.run(FragmentManager.java:532)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
at android.support.v4.app.FragmentManagerImpl.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.

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

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

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

回答by GreenROBO

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

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

这是因为您正在调用remove()add()具有null值的等方法。

请记住replace()= remove()->add()一一。

回答by ArtKorchagin

Try to use Fragments extending android.support.v4.app.Fragmentinstead of android.app.Fragmentand use the android.app.FragmentTransactioninstead of android.support.v4.app.FragmentTransaction

尝试使用 Fragments 扩展android.support.v4.app.Fragment代替android.app.Fragment并使用android.app.FragmentTransaction代替android.support.v4.app.FragmentTransaction

This bug already solved in this question:

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

Trying to remove fragment from view gives me NullPointerException on mNextAnim

尝试从视图中删除片段在 mNextAnim 上给了我 NullPointerException

Try it out.

试试看。