Ответ 1
Похоже, вы смешиваете две концепции здесь.
- Сохранение состояния в Configuration Configuration не предполагает сериализации. Если вы запросите
setRetainInstance()
дляFragment
, значит, он полностью останется в памяти и не будет воссоздан только для изменений конфигурации. Подобный механизм доступен для объектовActivity
, но им необходимо явно определитьObject
, который будет сохранен. Это работает черезActivity.onRetainNonConfigurationInstance()
, а не черезonSaveInstanceStae()
. - Другой механизм включает в себя сериализацию и возможно (возможно, не всегда, не уверен) ввода/вывода файловой системы, чтобы иметь возможность воспроизводить информацию о состоянии, даже если уничтожен
Activity
/Fragment
(что происходит независимо от его хостингаProcess
, кстати). Это работает черезActivity.onSaveInstanceState()
иFragment.onSaveInstanceState()
. - Конечно, вы можете использовать второй механизм для первого, тем самым замедляя то, как ваше приложение имеет дело с изменениями конфигурации. В зависимости от вашего внутреннего состояния замедление может меня незначительно повлиять.
Относительно ваших вопросов.
- "Мой фрагмент, напротив, позволяет содержать переменные, которые не могут быть сериализованы". Ну, то же самое верно и для вашего
Activity
. Он может содержать несериализуемые объекты, которые могут быть сохранены в конфигурационных изменениях, как описано выше. - "фрагмент не может быть сохранен на диск при завершении процесса и должен быть воссоздан при восстановлении активности". Нет, оба механизма доступны для обоих типов объектов.
Надеюсь, я мог бы внести свой вклад в это немного разъяснить.
Изменить после вашего первого комментария.
Относительно комментария:
- "
onRetainNonConfigurationInstance
устарел": Да. Я упомянул об этом в демонстрационных целях из-за конкретной формулировки в вашем вопросе. Кроме того, с устройствами Android 2, имеющими долю рынка на 46% в соответствии с сегодняшним днем (официальные данные Google), этот метод определенно останется в течение очень долгого времени, устарел или нет. - "Моя основная забота о том, что произойдет с экземпляром фрагмента, когда мой хостинг-процесс будет убит и удален из памяти": экземпляр вашего фрагмента будет удален из памяти, и, конечно, нет способа восстановить его с помощью его полное внутреннее состояние автоматически. Это делается только тогда, когда вы
setRetainInstanceState
в случае изменений конфигурации. (Но обратите внимание, что это относится к экземпляру, другими словами, к полному объекту.)
Относительно вашего редактирования:
- Еще раз да, ваш
Fragment
Bundle
будет сохранен и восстановлен в/изBundle
независимо отsetRetainInstanceState
, если вы используетеFragment.onSaveInstanceState()
для этой цели, для всего, что имеет смысл. - Неверно, что "все его видимое состояние" будет сохранено как текст, на который вы ссылаетесь; например, атрибут
visibility
не будет сохранен. Будь то ошибка или функция, которую я не знаю, но это факт. Но это только побочное замечание; Элементы пользовательского интерфейса сохраняют большую часть своего соответствующего состояния. - "состояние процесса записывается в файловую систему": Нет! Состояние объектов, которые могут сохранить свое состояние в
Bundle
и фактически реализовать сохранение своего состояния, будет сохранено вBundle
, это означает, что вы должны предоставить такую информацию самостоятельно, если хотите, чтобы вашFragment
сохранил некоторые информацию о состоянии. Кроме того, опять же: Нет, это связано не только с убийством процесса, но и с удалением объектовActivity
иFragment
, которые не видны; как показано в последней активности -Process
может остаться в живых. - "читаются для возобновления процесса": Нет,
Bundle
будет прочитан, чтобы передать его на перестройку объектов Activity и/или Fragment, в этом процессе ничего не делается автоматически (кроме объектов библиотеки которые сохраняют свое состояние, также восстанавливают свое состояние), но Android не "возобновляет" "процесс" из этихBundle
s. - "Поскольку сохранение фрагментов не связано с методами жизненного цикла": Опять же, я думаю, вы смешиваете эти два понятия. "Сохранение"
Fragment
выполняется только после изменений конфигурации _IF_, которые вы запрашиваете черезsetRetainInstance
, но мы в основном говорим о воссоздании объектовFragment
изBundle
здесь, что связано с методы жизненного цикла, описанные Google. - "Я не знаю, как сохранить, например, указатель на сетевое соединение": опять же, это должно быть утверждение, основанное на вашем путанице. Конечно, вы можете сохранить ссылку на сетевое подключение при изменении конфигурации (по запросу за
setRetainInstance
), потому что, когда это происходит, все просто хранится в памяти. Кроме того, даже если вашFragment
будет удален (потому что он стал невидимым), и ваш процесс все еще существует (поскольку он показывает следующее действие), вы можете (и должны) хранить ссылки на объекты, которые дорого воссоздавать, например как сетевое соединение, в вашем объектеApplication
, который существует до тех пор, пока ваш процесс живет (более или менее). Только когда все ваше приложение убито Android, вы теряете все, но сериализацию, которую мы обсуждаем, происходит гораздо чаще.
Ваше заключение:
Я пришел к выводу, что их обязательно нужно воссоздать, и поэтому методы жизненного цикла, по возможности, предпочтительнее, чем setRetainInstance (true). Имеет ли это предположение какой-либо смысл?
К сожалению, нет, поскольку вы смешиваете совершенно независимые понятия.
Я дам ему последнюю попытку:
- Вам нужно сохранить ссылку на сетевое подключение, которая вам нужна во всем приложении, в вашем объекте
Application
, потому что это будет отвратительный пользовательский интерфейс, если вы создадите его с нуля на регулярной основе в своем приложении. - Ваш объект
Application
будет только умирать, если Android убьет ваше приложение. - Объекты
Activity
иFragment
будут удалены из вашего приложения регулярно, когда пользователь перемещается вперед в вашем приложении. - Когда пользователь нажимает "назад", Android будет повторно создавать объекты
Activity
иFragment
изBundle
с использованием методов жизненного цикла. Сохранение чего-то в Bundle имеет смысл, если у вас есть дорогостоящие вычисления для повторного создания внутреннего состояния. Вы можете жить без механизмаBundle
, потому что Android всегда будет сохранятьIntent
, поэтому, если вы ничего не сделаете, вы начнете без сохраненного состояния. - При изменении конфигурации Android позволяет оптимизировать работу пользователя, сохраняя объекты в памяти при изменении конфигурации. Здесь используются методы жизненного цикла
Activity
, и это зависит от вашей реализации, чтобы эффективно использовать сохраненные данные. ДляFragment
s это означает, чтоsetRetainInstance' comes into play: Your
Fragment` выживет при изменении конфигурации в памяти, если вы установите его.