NullPointerException related to FragmentManager.po

2019-04-06 22:48发布

问题:

I have an Android app where I have an activity and a stack of fragments.

Using Crashlytics, I have received a single instance of the following Exception:

Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.FragmentManager.popBackStack(java.lang.String, int)' on a null object reference
       at com.company.app.Fragment$7$2.onClick(Fragment.java:397)
       at android.view.View.performClick(View.java:5197)
       at android.view.View$PerformClick.run(View.java:20926)
       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(Method.java)
       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 code that is producing this error is:

okButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        dialog.dismiss();
        // The next line produces the Exception
        getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                // Other code...
        }, 250);
    }
});

Based on the testing I have done with this app, the user for which this Exception occurred, and the fact that is has only occurred once, I am thinking that this Exception occurs when some strange consolidation of circumstances occurs. (Basically, I can't reproduce this Exception on my end.) I am assuming this has to do with the user backgrounding my app and then resuming it at a later time, and then the getFragmentManager() call returns a null.

So, I know that I can "fix" this with code like the following (found this as an applied fix to a GitHub repository):

FragmentManager fm = getFragmentManager();
if (fm != null) fm.popBackStack();

While I realize that the code above will "fix" the problem in that it will avoid the NPE, (thus stopping the app from crashing), it doesn't really "fix" the problem by allowing my app to function as desired. The Fragment in question is #3 in a stack of fragments, like this:

#1 --> #2 --> #3

The desired behavior for the app is to respond to this button click by popping back to Fragment #1 being visible. Merely adding in the code above seems like it would keep the app from crashing, but not change the app's UI in the desired manner.

What am I doing wrong such that when my app resumes, it's "fragment state" is out of whack?

回答1:

I have never faced an issue with the getFragmentManager() being null so I am assuming it is the popBack part of the statement that is causing the issue. Here is one possible solution to prevent a crash and handling the exceptions. If it only happened once, it may have been a rare instance.

okButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (getSupportFragmentManager() != null) {
            // Assuming the getFragmentManager() is not the Issue, rather the popBackStack is the issue
            try {
                getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
            } catch (Exception e) {
                // Recreate a new instance of your first fragment here.
            }
        } else {
            /*
             getFragmentManager() == null 
             I have never faced an issue when getFragmentManager() == null, but I would restart the activity if that is the case
            */

        }
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {

            }
        }, 250);
    }
});