Android的FragmentManager BackStackRecord.run抛出NullP

2019-06-21 04:17发布

与片段工作时,我有时会出现以下情况例外:

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()BackStackRecord通过称为execPendingTransactions()当它试图从管理器中删除的片段。

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

我似乎无法弄清楚到底是什么造成的? 我认为这与除去碎片的时候没有被清理右片段返回堆栈做。

Answer 1:

回答我的问题:

这个例外是(最终)当你调用抛出FragmentTransaction.remove(null); FragmentTransaction.commit();

编辑:而且也一样,两次盘旋shinyuX在注释中指出; 打电话时的show(null)add(null)attach(null)detach(null)的方法,大概也hide(null)

打完电话后commit()该交易将在FragmentManager排队。 其结果是,当被处理的操作显式调用后FragmentManager.executePendingTransactions()或当FragmentManager队列线程调用它,它抛出一个NullPointerException

以我为例,我是在维护一个全局对象片段的状态。 还有我检查如果上述DNA片段示出或没有,然后除去可见片段。 但是,因为我开始了新的FragmentActivity,这些国家仍然设置为true,而他们不可见。 因此,这是一个设计错误。

除了固定的设计错误,解决方法很简单:检查是否FragmentManager.findFragmentByTag()返回null删除片段之前。



Answer 2:

的原因之一正好是调用

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

fragment为null



Answer 3:

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

因此,它的工作原理,当改变标签,但如果我按后退按钮,我得到了同样的错误。

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

}
}


文章来源: Android FragmentManager BackStackRecord.run throwing NullPointerException