Ответ 1
Небольшое погружение в источники
В FragmentManager
существует логическая переменная, называемая mStatedSaved
. Эта переменная отслеживает сохраненное состояние в зависимости от обратных вызовов жизненного цикла активности. Вот метод, который генерирует известное исключение:
private void checkStateLoss() {
if (mStateSaved) {
throw new IllegalStateException(
"Can not perform this action after onSaveInstanceState");
}
...
}
Это означает, что как только эта переменная будет изменена на false
, транзакции фрагмента могут быть выполнены. Эта переменная станет true
, когда состояние активности будет сохранено, т.е. onSaveInstanceState()
.
Вернуться к вопросу
Вы сказали, что ранее у вас были проблемы с транзакцией из onActivityResult()
. Это должно означать, что ранее mStateSaved
не назначался false
, и в настоящее время он есть. На деле это так.
Здесь onActivityResult()
реализация из выпуска O:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
mFragments.noteStateNotSaved();
...
}
Где noteStateNotSaved()
будет делать следующее:
public void noteStateNotSaved() {
...
mStateSaved = false;
...
}
Напротив, вы можете увидеть реализацию onActivityResult()
версии Jelly Bean:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
int index = requestCode>>16;
if (index != 0) {
index--;
if (mFragments.mActive == null || index = mFragments.mActive.size()) {
Log.w(TAG, "Activity result fragment index out of range: 0x"
+ Integer.toHexString(requestCode));
return;
}
Fragment frag = mFragments.mActive.get(index);
if (frag == null) {
Log.w(TAG, "Activity result no fragment exists for index: 0x"
+ Integer.toHexString(requestCode));
} else {
frag.onActivityResult(requestCode&0xffff, resultCode, data);
}
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
Ничто не изменило бы значение поля mStateSaved
, которое создало бы исключение, если транзакция будет совершена.
Фактически в выпуске Kit-Kat была представлена строка mFragments.noteStateNotSaved()
. Как вы можете видеть комментарий коммита, сделанный Dianne Hackborn:
ActivityFragment должен очистить флаг, что состояние сохраняется, когда оно получает
onNewIntent()
. Это может произойти до того, как возобновлено, так что мы, возможно, еще не очистили его. Также необходимо сделать то же самое вещь дляonActivityResult()
.
Сумма
Является
onActivityResult()
теперь гарантированным безопасным местом для транзакций фрагментов?
Предполагая, что вы используете источники, которые включают commit 4ccc001, который был сделан в октябре 2012 года - да, это безопасное место для транзакций фрагментов.