Когда Fragment заменяется и помещается в задний стек (или удаляется), он остается в памяти?

Является ли поведение похожим на то, как работают действия? Например, с помощью «Действия» он работает следующим образом:

Активность A запускает активность B , а B – на экране, система может удалить A из памяти, если она необходима системе. После нажатия BACK, A будет воссоздан в память, как если бы он никогда не оставался в первую очередь.

Я искал четкое объяснение того, что происходит с памятью с Фрагментами и ничего не нашел. Это работает так же? Например:

Активность C имеет фрагмент F в своем макете. Затем в какой-то точке F заменяется фрагментом G , но F сохраняется в его заднем стеке.

Будет ли F оставаться в памяти до тех пор, пока C не будет убит или не будет удалена системой по мере необходимости?

На самом деле я спрашиваю, есть ли у меня риск нехватки памяти, если у меня есть задний стек сложных фрагментов в одном действии?

Взгляните на это: BackStackRecord.Op.fragment

Таким образом, фрагменты хранятся в фоновом стеке. Обратите внимание на живую ссылку, WeakReference не используются ни WeakReference ни SoftReference .

Теперь это: FragmentManagerImpl.mBackStack

Вот где менеджер хранит задний стек. Simple ArrayList , также, без WR или SR.

И, наконец, это: Activity.mFragments

Это ссылка на диспетчер фрагментов.

GC может собирать только объекты, у которых нет ссылок на живое (недоступны из любого потока). Это означает, что до тех пор , пока ваша активность не будет уничтожена (и, таким образом, ссылка FragmentManager исчезнет), GC не сможет собрать ни одного из фрагментов в фоновом стеке .

Обратите внимание, что когда Activity уничтожается и сохраняет состояние (например, когда вы поворачиваете устройство в альбомном режиме), он не сохраняет фактические объекты Fragment в стеке, только их состояния – объекты Fragment.FragmentState , то есть фактические фрагменты в обратном стеке Воссоздается каждый раз, когда активность воссоздается с сохраненным состоянием.

Надеюсь это поможет.

PS Итак, короче: да, вы можете исчерпать память, добавив Fragments в задний стек, а также добавив слишком много просмотров для просмотра иерархии.

UPD Учитывая ваш пример, F останется в памяти до тех пор, пока C не будет убит. Если C убит, а затем воскрешен с другой конфигурацией – F будет уничтожен и реинкарнирован в другом объекте. Таким образом, область памяти F находится вокруг до тех пор, пока C не потеряет состояние или задний стек.

Прошу прощения за то, что я не смог предоставить вам какой-то официальный источник информации, но мне было любопытно также узнать, что произойдет, и решил проверить его. И, согласно моим тестам, да, вы рискуете исчерпать память.

Мне пришлось добавить невероятное количество фрагментов (более ста) в цикл for для OutOfMemoryError , но это произошло. И, проверяя мои журналы, я видел, что onCreate() и onCreateView() вызывались много раз, но onSaveInstance() , onPause() и onDestroy не вызывались.

Для справки, это то, как я добавил фрагменты в backstack:

 getSupportFragmentManager().beginTransaction().add(R.id.scene_fragment_container, mSceneFragment).addToBackStack("FOOBAR").commit(); 

И добавленные фрагменты были несколько простыми: ImageView , EditText , пара TextViews , SeekBar и ListView .

Но если вы не держите в памяти огромное количество данных, это не должно быть проблемой.

Позже я попробовал добавить только 50 в стопку, убив приложение и перезапустив его. И, как я надеялся / догадался, все фрагменты были восстановлены (и onSaveInstance() и onPause() ), поэтому моя реализация жизненного цикла не была проблемой, вызвавшей OutOfMemoryError .

С сайта developer.android.com/guide/topics/fundamentals/fragments.html

Фрагмент всегда должен быть встроен в действие, и жизненный цикл фрагмента напрямую зависит от жизненного цикла хост-активности. Например, когда действие приостанавливается, то есть все фрагменты в нем, и когда действие уничтожается, так же как и все фрагменты. Однако, пока выполняется действие (оно находится в состоянии возобновленного жизненного цикла), вы можете самостоятельно управлять каждым фрагментом, например, добавлять или удалять их. Когда вы выполняете такую ​​транзакцию фрагмента, вы также можете добавить ее в задний стек, который управляется активностью – каждая запись заднего стека в активности представляет собой запись о транзакции фрагмента, которая произошла. Задний стек позволяет пользователю отменить транзакцию фрагмента (перемещаться назад), нажав кнопку BACK.

Да, вы можете исчерпать память, создавая слишком много фрагментов в одном действии. Фрагменты будут уничтожены только в том случае, если содержит актив.

Intereting Posts
MapView без расширения MapActivity Android – потоковое видео на локальном HTTPS-сервере: сертификат SSL отклонен Режимы намерения Android google.navigation? Как сказать OkHttpClient игнорировать кеш и принудительно обновить сервер? Уведомление об обнаружении службы доступности Android Android – DDMS показывает сообщение: logcat read: Недопустимый аргумент Создание jar для проекта android в eclipse Андроид expandablelistview не расширяет или не получает события кликов Что делает определенные классы андроидов «must -keep»? Как использовать карту OSM в приложении Android. Есть ли учебник, чтобы узнать об использовании OSM в android.? Существуют ли общие конфигурации AVD где-нибудь, которые можно загрузить / просмотреть? Невозможно выполнить dex: несколько файлов dex определяют Lcom / facebook / android / AsyncFacebookRunner $ 1; Многопользовательская функция JellyBean в эмуляторе от Ubantu Идентификатор GCM ID Android возвращает в некоторых случаях «MESSENGER», в то время как работает отлично в большинстве случаев. Не удалось найти причину Read failed: EBADF (неверный номер файла)