65

使用 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()ofBackStackRecord被调用execPendingTransactions()时,当它试图从管理器中删除一个片段时,就会发生异常。

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

我似乎无法弄清楚究竟是什么原因造成的?我认为这与删除碎片时没有正确清理碎片的后台有关。

4

3 回答 3

160

回答我自己的问题:

当您调用FragmentTransaction.remove(null);FragmentTransaction.commit();

编辑:而且,就像 Twice Circled 和 shinyuX 在评论中指出的那样;调用show(null)or add(null), attach(null)anddetach(null)方法时,可能还有hide(null)

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

就我而言,我在全局对象中维护片段状态。在那里我检查了片段是否显示,然后删除了可见的片段。但是因为我启动了一个新的 FragmentActivity,所以这些状态在不可见时仍然设置为 true。所以这是一个设计错误。

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

于 2012-11-15T10:03:21.170 回答
0

它发生的一个原因是调用

getSupportFragmentManager().beginTransaction().remove(fragment)

fragment为空

于 2018-08-20T08:51:08.623 回答
-2

我不使用标签来创建片段(它们就像 TabBar 容器一样工作)。

因此,它在更改 Tab 时有效,但如果我按下后退按钮,我会遇到同样的错误。

在 onDestroyView 方法中,我找到了 FragmentManager#findFragmentById 的片段实例,但是 FragmentManager#findFragmentByTag 返回 null,当然。

class MyFragment extends ListFragment {

@Override
public void onDestroyView() {
    super.onDestroyView();

    if (this.mapFragment != null
            && getFragmentManager().findFragmentById(
                    this.mapFragment.getId()) != null) {

        getFragmentManager().beginTransaction().remove(this.mapFragment)
                .commit();
        this.mapFragment = null;
    }

}
}
于 2013-03-12T18:25:06.033 回答