Аргументы фрагмента не содержат данных после извлечения из backstack

Итак, у меня есть фрагмент - фрагмент A - который содержит объект - объект O - используемый для настройки TextView и других элементов. Для создания экземпляра фрагмента я использую статический метод A.getInstance (O). Объект O сериализуем, поэтому я могу отправить его новому экземпляру фрагмента A через Bundle, используя instance.setArguments и так далее.

Я получаю O в методе onCreate для A и настраиваю поля с помощью O в onViewCreated. Пока все работает нормально. После того как я заменяю A другим фрагментом - фрагментом B - и возвращаюсь от B к A, набор аргументов больше не содержит объект O, и я получаю исключение NullPointerException. Сам пакет не является нулевым, но он не содержит O.

Я использую этот метод для замены фрагментов:

public void replaceCurrentFragment(Fragment fragment) {
        FragmentTransaction fragmentTransaction = context.getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.frame, fragment).addToBackStack(null).commit();
}

Фрагмент A также отображается с помощью описанного выше метода.

Что я делаю неправильно?


person Ionuț Ciuta    schedule 11.09.2015    source источник
comment
Вы восстанавливаете объект O только из Fragment#getArgumnets()? Вы пытались сохранить и восстановить объект O из состояния экземпляра фрагмента?   -  person Oleh Toder    schedule 11.09.2015
comment
Я сохраняю объект O в экземпляре фрагмента A во время onCreate. Проблема в том, что я не получаю «О» во второй раз, когда захожу в onCreate.   -  person Ionuț Ciuta    schedule 11.09.2015
comment
Я имею в виду, вы переопределили фрагмент # onSaveInstanceState, чтобы сохранить свой объект, а затем искали его в Bundle, переданном в onCreate (Bundle savedInstanceState)?   -  person Oleh Toder    schedule 11.09.2015
comment
Нет, я этого не делал. Это необходимо? В настоящее время я получаю пакет с помощью Fragment # getArguments (). Разве он не должен каждый раз возвращать один и тот же Bundle?   -  person Ionuț Ciuta    schedule 11.09.2015


Ответы (1)


Обратите внимание на метод Fragment#onCreate(Bundle savedInstanceState). Когда вы впервые создали свой фрагмент из метода A#getInstance, этот переданный пакет будет нулевым. Вы просто извлечете свои объекты O из метода Fragment#getArguments, как и вы.
Чтобы сохранить объект для использования в будущем, переопределите Fragment#onSaveInstanceState и сохраните там объект O (может выглядеть так)

private static final String EXTRA_MY_OBJECT = "com.example.extra_my_object";

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putSerializable(EXTRA_MY_OBJECT, mMyObject);
}

А затем в Fragment#onCreate вы можете получить свой объект из переданного Bundle Вот так:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (savedInstanceState != null) {
        mMyObject = savedInstanceState.getSerializable(EXTRA_MY_OBJECT);
    }
    if (mMyObject == null) {
        //fragment was created for first time probably, or something went wrong
        //try to get your object from getArguments

    }
}
person Oleh Toder    schedule 11.09.2015
comment
Я ценю ваш ответ, однако onSaveInstanceState не вызывается, когда я заменяю фрагмент. Итак, когда я возвращаюсь назад, я сталкиваюсь с той же проблемой. Когда текущий фрагмент заменяется, последний обратный вызов жизненного цикла - onStop, и onSaveInstanceState никогда не вызывается до этого момента. Так что да. . . - person Ionuț Ciuta; 14.09.2015