与FragmentManager.popBackStack相关的NullPointerException。 怎么解决?

我有一个Android应用程序,我有一个活动和一堆片段。

使用Crashlytics,我收到了以下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) 

产生此错误的代码是:

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

基于我对此应用程序所做的测试,发生此exception的用户以及仅发生过一次的事实,我认为当出现某种奇怪的情况合并时会发生此Exception 。 (基本上,我无法在我的最终重现此Exception 。)我假设这与用户后台我的应用程序然后在以后恢复它,然后getFragmentManager()调用返回null

所以,我知道我可以用以下代码“修复”这个(发现这是对GitHub存储库的应用修复):

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

虽然我意识到上面的代码将“修复”问题,因为它将避免NPE ,(从而阻止应用程序崩溃),它并没有真正“修复”问题,允许我的应用程序按需运行。 有问题的Fragment是一堆片段中的#3,如下所示:

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

应用程序的所需行为是通过弹回到可见的Fragment #1来响应此按钮单击。 仅仅添加上面的代码似乎会使应用程序崩溃,但不会以所需的方式更改应用程序的UI。

我做错了什么,当我的应用程序恢复时,它的“碎片状态”是不是很糟糕?

我从来没有遇到过getFragmentManager()为null的问题所以我假设它是导致问题的语句的popBack部分。 这是防止崩溃和处理exception的一种可能的解决方案。 如果它只发生过一次,那可能是一个罕见的例子。

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