Android FragmentManager BackStackRecord.run抛出NullPointerException

Nic*_*ckL 65 java android android-fragments fragmentmanager

使用Fragments时,我有时会遇到以下异常:

FATAL EXCEPTION: main
java.lang.NullPointerException
    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:591)
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1416)
    at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:420)
    at android.os.Handler.handleCallback(Handler.java:615)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4745)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    at dalvik.system.NativeStart.main(Native Method)
Run Code Online (Sandbox Code Playgroud)

当调用from时,当它尝试从管理器中删除片段时run(),会发生异常.BackStackRecordexecPendingTransactions()

case OP_REMOVE: {
  Fragment f = op.fragment;
  f.mNextAnim = op.exitAnim; <----
  mManager.removeFragment(f, mTransition, mTransitionStyle);
}
break;
Run Code Online (Sandbox Code Playgroud)

我似乎无法弄清楚究竟是什么导致了这个?我认为这与拆除碎片时未正确清理的碎片堆叠有关.

Nic*_*ckL 160

回答我自己的问题:

当你调用FragmentTransaction.remove(null);和时,(最终)会抛出此异常FragmentTransaction.commit();

编辑:还有,像Twice Circled和shinyuX在评论中指出的那样; 在调用时show(null)add(null),attach(null)detach(null)方法,大概也hide(null)

调用后commit(),事务将在FragmentManager中排队.因此,在显式调用后处理操作时FragmentManager.executePendingTransactions(),或者当FragmentManager队列线程调用它时,它会抛出一个NullPointerException.

在我的例子中,我在一个全局对象中维护片段状态.在那里我检查了片段是否显示,然后删除了可见的片段.但是因为我开始了一个新的FragmentActivity,这些状态仍然设​​置为true,而它们不可见.所以这是一个设计错误.

除了修复设计错误之外,解决方案很简单:在删除片段之前检查是否FragmentManager.findFragmentByTag()返回null.

  • 很好的答案 - 这有助于我解决自己的问题.有一点需要注意,当你调用FragmentTransaction.show(null),.hide(null)等时,你会得到同样的错误.不仅仅是.remove(null).希望这将有助于其他人追查他们的问题. (14认同)
  • 这应该完全崩溃在实际的`hide`,`show` ...调用,这样堆栈跟踪实际上是可用的...... (2认同)