Подтвердить что ты не робот

Как новый FragmentTransaction commitNow() работает внутри?

Новый commitNow() метод, добавленный в Android N, и поддержка библиотеки версии 24 имеет ограниченную и немного запутанную документацию.

Выполняет транзакцию синхронно. Любые добавленные фрагменты будут инициализированы и полностью доведены до состояния жизненного цикла их хост и любые удаленные фрагменты будут разорваны соответственно до этот вызов возвращается. Выполнение транзакции таким образом позволяет фрагменты, которые будут добавлены как выделенные, инкапсулированные компоненты, которые контролировать состояние жизненного цикла своего хоста, обеспечивая при этом более прочное заказывать гарантии, когда эти фрагменты полностью инициализируются и готов. Фрагменты, управляющие представлениями, будут иметь созданные те взгляды и прилагается.

Вызов commitNow предпочтительнее вызова commit() а затем FragmentManager.executePendingTransactions() в качестве последнего будет иметь побочный эффект от попыток совершить все в настоящее время ожидающих транзакций, является ли это желаемым поведением или нет.

Транзакции, совершенные таким образом, не могут быть добавлены в FragmentManager, так как это приведет к потере других ожидаемых заказывающие гарантии для других асинхронно совершенных транзакций. Этот метод вызовет IllegalStateException, если транзакция ранее запрошенный для добавления в задний стек с addToBackStack (String).

Транзакция может быть совершена только с этой до его сохранения, сохраняя его состояние. Если commit совершает попытку после этой точки, будет выбрано исключение. Это связано с тем, что состояние после фиксации может быть потеряно, если активность необходимо восстановить из своего состояния. См. CommitAllowingStateLoss() для ситуации, когда может быть хорошо потерять фиксацию.

Я выделил выделенную жирным шрифтом часть, которая, по моему мнению, путается.

Итак, мои основные вопросы/вопросы:

1 - НЕ МОГУТ добавить? Он говорит, что я получу исключение IllegalStateException, так оно будет или не будет добавлено?

2 - Я согласен с тем, что я не могу использовать это, если мы хотим добавить фрагмент в backstack. То, что он не говорит, заключается в том, что вы получаете это исключение:

java.lang.IllegalStateException: This transaction is already being added to the back stack

!!!!????

Итак, я не могу позвонить addToBackStack(String) сам, потому что он внутренне вызывает это для меня? Извините, но... что? Зачем? что, если я не хочу, чтобы он был добавлен в заднюю часть? И что, если я попытаюсь использовать этот фрагмент из backstack позже, но потому что он НЕ МОЖЕТ быть добавлен, позже его нет?

Похоже, что это что-то ожидаемое, если я использовал commitAllowingStateLoss(), но я вижу, что commitNowAllowingStateLoss() также существует, поэтому... в какой логике это происходит?

TL; DR

Как функция commitNow() работает внутренне относительно backstack?

4b9b3361

Ответ 1

Хорошо, что исходный код Android - это Open Source, когда мы столкнулись с таким вопросом!

Ответ

Итак, давайте посмотрим на источник BackStackRecord здесь

@Override
public void commitNow() {
    disallowAddToBackStack();
    mManager.execSingleAction(this, false);
}

@Override
public FragmentTransaction disallowAddToBackStack() {
    if (mAddToBackStack) {
        throw new IllegalStateException(
                "This transaction is already being added to the back stack");
    }
    mAllowAddToBackStack = false;
    return this;
}

И mAddToBackStack будет установлено значение true, если вы вызываете addToBackStack в своей транзакции.

Итак, чтобы ответить на ваш вопрос, no addToBackStack не вызывается внутренне, когда вы вызываете commitNow(), это сообщение об ошибке, которое является двусмысленным. Я думаю, что это должно сказать You're not allowed to add to backstack when using commitNow() вместо текущего сообщения.

Бонус:

Если мы углубимся в исходный код FragmentManager здесь, commitNow() на самом деле делает почти то же самое, что и executePendingTransactions(), как написано выше, но вместо выполнения всех ранее совершенных транзакций commitNow() будет выполнять только транзакцию.

Я думаю, что основная причина, по которой commitNow() не позволяет добавлять в backstack, поскольку она не может гарантировать отсутствие другой ожидающей транзакции. Если commitNow() может добавить к backstack, есть вероятность, что мы сможем разорвать нашу заднюю последовательность, которая приведет к неожиданным вещам.