web-dev-qa-db-ja.com

Android FragmentManager BackStackRecord.run throwing NullPointerException

フラグメントを操作しているときに、次の例外が発生することがあります。

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()を介してBackStackRecordexecPendingTransactions()が呼び出され、マネージャーからフラグメントを削除しようとしたときに発生します。

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

何がこれを引き起こしているのか正確に把握できないようです。フラグメントを削除するときに、クリーンアップされていないフラグメントのバックスタックに関係していると思います。

65
NickL

自分の質問に答える:

この例外は(最終的に)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を返したかどうかを確認してください。

160
NickL

それが起こる1つの理由はそれを呼び出すことです

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

fragmentはnull

0
Pavlo Zorya