Фрагмент IllegalStateException - commit (), вызывающий потерю состояния - PullRequest
0 голосов
/ 31 мая 2018

У меня есть FragmentStatePagerAdapter, который показывает 3 вкладки, из которых 1-я вкладка (фрагмент) фиксирует транзакцию FragmentTransaction внутри своего onCreateView ().Для некоторых пользователей я вижу исключение IllegalStateException, вызванное потерей состояния commit ().

После прочтения нескольких вопросов и ответов о переполнении стека и сообщения в блоге Алекса Локвуда о Транзакциях с фрагментами и потере состояния активности я лучше понимаю, что вызывает потерю состояния, и могу взять несколькоподходы.

  1. Я могу переместить свой фрагмент коммита в onPostResume.
  2. Я могу переместить мой фрагмент коммита в onCreate () - возможно, самый безопасный.

Однако, внутри onCreateView () много логики, и если бы я использовал вышеуказанный подход, я мог бы представить ошибки регрессии.Мне интересно, так как onCreate () в конечном итоге вызовет onCreateView (), если это нормально, просто проверить сохраненный InstanceState для нуля.Решит ли это проблему?

Вот мой текущий код:

@Override
public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    ...
    FFragment frag = new FFragment();
    frag.setDateSelected(mDateSelected);
    getFragmentManager().beginTransaction()
            .add(R.id.container, frag, FRAG_TAG)
            .commit();
    ...
}

Что я думаю, что исправит потерю состояния:

@Override
public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    ...
    if(savedInstanceState == null) {
        frag = new FFragment();
        frag.setDateSelected(mDateSelected);
        getFragmentManager().beginTransaction()
                .add(R.id.container, frag, FRAG_TAG)
                .commit();
    } else {
        frag = (FFragment) getSupportFragmentManager()
            .findFragmentByTag(FRAG_TAG);
    }
    ...
}

Почему я спрашиваю этоа не просто реализовать и протестировать это?Я пытался убить активность через ADB и DDMS, но не смог воспроизвести потерю состояния - таким образом, спрашивая, сработает ли этот подход.Или мне нужно сделать неизбежное и переместить коммит в onCreate или onPostResume ()?

Есть ли другой способ проверить потерю состояния триггера?

1 Ответ

0 голосов
/ 31 мая 2018

Есть пара вещей, которые вы ошиблись

  1. Вы используете getFragmentManager () и getSupportFragmentManager () внутри фрагмента, вы должны всегда использовать getChildFragmentManager () при использовании вложенных фрагментов

  2. OnResumeFragments () и onCreate, о которых говорил Алекс, относятся к активности, а не к фрагментам, внутри фрагмента нет такого метода

  3. Решение, которое вы предлагаете, предназначено для совершенно другой вещи, оно используется, когда действие воссоздается из backstack

Решение будет состоять в том, чтобы переместить ваш код в метод onViewCreated () вашего фрагмента.и использовать childFragmentManager, я использую viewpager внутри фрагмента и инициализирую его внутри onViewCreated (), до сих пор не сталкивался с такой проблемой

...