Предотвращение восстановления фрагментов в 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()
.