it-swarm.com.ru

Android FragmentManager BackStackRecord.run выбрасывает исключение 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() из BackStackRecord вызывается через execPendingTransactions(), когда он пытается удалить фрагмент из менеджера.

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

Я не могу понять, что именно вызывает это? Я думаю, что это связано с тем, что фрагменты фрагментов не очищаются при удалении фрагментов.

65
NickL

Отвечая на мой собственный вопрос:

Это исключение (в конечном итоге) выдается при вызове FragmentTransaction.remove(null); и FragmentTransaction.commit();

Правка: А также, как два раза обведено кружком и блестящие X указывают в комментарии; при вызове методов show(null) или add(null), attach(null) и detach(null) и, возможно, также hide(null)

После вызова commit() транзакция будет помещена в очередь в FragmentManager. В результате, когда операция обрабатывается после явного вызова FragmentManager.executePendingTransactions() или когда поток очереди FragmentManager вызывает ее, она выдает NullPointerException.

В моем случае я поддерживал состояния фрагментов в глобальном объекте. Там я проверил, показывает ли фрагмент или нет, а затем удалил видимые фрагменты. Но поскольку я запустил новый FragmentActivity, эти состояния все еще были установлены в true, но они не были видны. Так что это ошибка дизайна.

Помимо исправления ошибки проектирования, решение было простым: проверьте, вернул ли FragmentManager.findFragmentByTag()null перед удалением фрагмента.

159
NickL

Одна из причин, почему это происходит, вызывает 

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

в то время как fragment является нулевым

0
Pavlo Zorya