Предотвращение восстановления фрагментов в Android

Мы используем фрагменты, и нам не нужно, чтобы они автоматически восстанавливались при восстановлении Activity. Но Android каждый раз, когда вызывается Activity::onCreate(Bundle savedInstanceState)super.onCreate(savedInstanceState), восстанавливает фрагменты, даже если мы используем setRetainInstance (false) для этих фрагментов.

Кроме того, в те Fragments Fragment.performCreateView() вызывается непосредственно без прохождения Fragment::onAttach() и т.д. Кроме того, некоторые из полей имеют нулевое значение внутри восстановленного Fragment...

Кто-нибудь знает, как запретить Android восстанавливать фрагменты?

P.S. Мы знаем, что в случае воссоздания Activity для изменений config это можно сделать, добавив в манифест a ndroid:configChanges="orientation|screenSize|screenLayout. Но как насчет воссоздания активности в случае автоматической очистки памяти?

Ответ 1

Мы закончили добавлением активности:

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

Он подавляет любые сохраненные данные в цикле создания/воссоздания Activity и избегает автоматического повторного создания фрагментов.

Ответ 2

@goRGon ответ был очень полезен для меня, но такое использование вызывает серьезные проблемы, когда есть дополнительная информация, которую вам нужно переслать в свою деятельность после воссоздания.

Вот улучшенная версия, которая удаляет только "фрагменты", но сохраняет все остальные параметры.

Идентификатор, удаленный из пакета, является частью класса android.support.v4.app.FragmentActivity как FRAGMENTS_TAG. Разумеется, он может меняться со временем, но этого не ожидается.

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

/**
 * Improve bundle to prevent restoring of fragments.
 * @param bundle bundle container
 * @return improved bundle with removed "fragments parcelable"
 */
private static Bundle createBundleNoFragmentRestore(Bundle bundle) {
    if (bundle != null) {
        bundle.remove("android:support:fragments");
    }
    return bundle;
}

Ответ 3

Те, кто получил NPE с ViewPager при использовании этого метода, описанного в принятом ответе, пожалуйста, переопределите

ViewPager.onRestoreInstanceState(Parcelable state)

и вызов

super.onRestoreInstanceState(null);

вместо.

Ответ 4

Я удалил фрагменты в Activity onCreate.

Ответ 5

У меня также был ViewPager поэтому я проверил ViewPager на ViewPager фрагментов и удалил их в onCreate().

Используя, например, этот поток: Удалить все фрагменты из контейнера.

FragmentManager fm = getSupportFragmentManager();
for (Fragment fragment: fm.getFragments()) {
  fm.beginTransaction().remove(fragment).commitNow();
}

commitNow() для удаления фрагментов синхронно.

Ответ 6

У меня была проблема с TransactionTooLargeException. К счастью, после использования tolargetool я обнаружил, что фрагменты (android: support: фрагменты) были в памяти, и транзакция стала слишком большой. Итак, наконец, я сделал это, и это сработало отлично.

@Override
public void onSaveInstanceState(final Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putSerializable("android:support:fragments", null);
}

Ответ 7

Просмотр иерархии в автоматическом восстановлении. Итак, в Fragment.onCreateView() или Activity.onCreate() вам нужно восстановить все виды (из xml или программно). Каждая группа просмотра, содержащая фрагмент, должна иметь тот же идентификатор, что и при его создании в первый раз. После создания иерархии представлений Android восстанавливает все фрагменты и помещает их в нужную ViewGroup благодаря идентификатору. Скажем, что Android запоминает идентификатор ViewGroup, на котором был фрагмент. Это происходит где-то между onCreateView() и onStart().