Подтвердить что ты не робот

Когда вид прикреплен и отсоединен?

Этот вопрос не о том, как определить, прикреплен или отключен вид.

В общем, когда вид прикреплен или отсоединен? Есть ли схема жизненного цикла для этого?

Чтобы уточнить, я ищу ответы на то, что происходит, когда: активность отправлена ​​на задний план, непрозрачный вид сверху, видимость, установленная на GONE, просмотр завышен, родительский и т.д. Это не исчерпывающий список - Я просто хочу понять, как написание и снятие взглядов работает на фундаментальном уровне.

Обновите дополнительные примеры того, что я пытаюсь получить:

Как насчет фрагментов или действий?
Как насчет вложенных представлений - в каком порядке отображаются прикрепленные/отсоединенные представления (parent- > child или child- > parent)?
Учитываются ли измерения до их прикрепления или после?
Как об использовании addView() в ViewGroup вручную?

Изменить: Сводка:

  • Для видов деятельности представления добавляются в setContentView(). Представления отделяются в onDestroy() или когда setContentView() вызывается с другим видом.
  • Для фрагментов, представления прикреплены после onViewCreated() завершает и отделяются после завершения onDestroyView().
  • Для ViewGroups представления добавляются в addView() и отсоединяются в removeView()
  • setVisibility() не влияет на прикрепленное состояние представления
4b9b3361

Ответ 1

Из официальной документации:

Активность - это единая целенаправленная вещь, которую пользователь может сделать. Почти все действия взаимодействуют с пользователем...

Первое, что нужно отметить, - это не обязательность того, чтобы действия были связаны с макетом. У вас может быть активность без интерфейса (и, следовательно, нет представления). Android даже не указывает тему UI для этого.

Перейдя к вашему вопросу - в момент, когда вы вызываете setContentView (просмотр), объект привязывается к Activity. Обычно это вызывается внутри метода onCreate(). Причина, по которой вы обычно это делаете в методе onCreate(), заключается в том, что большая часть инициализации выполняется там. И как вы могли бы инициализировать свои виджеты, если представление не было завышено и не привязано к Activity? Следовательно, если у вас есть представление, вы почти неизменно в конечном итоге вызываете setContentView() внутри вашего метода onCreate(), предшествующего любой другой инициализации.

Но означает ли это, что представление (если оно существует) должно быть привязано к активность только внутри метода onCreate()?

Чтобы ответить на этот вопрос, посмотрим, как выглядит жизненный цикл Activity. Вы начинаете свое приложение:

onCreate() → onStart() → onResume()//Они вызываются последовательно

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

Итак, почему бы не раздуть и не добавить активность в onResume() и сделать все там инициализации?

Конечно, можно. Но представьте, что произойдет, когда появится диалог (частично непрозрачный вид)? Теперь активность частично покрыта и находится в фоновом режиме. Вызывается метод onPause(). Макет по-прежнему привязан к Activity на этом этапе. Вы предпринимаете некоторые действия и отклоняете диалог. onResume() вызывается. Макет будет завышен снова. Все инициализации произойдут снова, и вы потеряете свое состояние. Даже если у вас не было много возможностей для инициализации, вы все равно будете делать довольно дорогой вызов, снова вызов onCreate(). И вы хотите избежать этого на мобильных устройствах с ограниченными ресурсами.

Что происходит, когда появляется непрозрачное представление, и теперь активность фон, но все еще работает (например, входящий телефонный звонок или открытие другого действия)?

Теперь выполняются следующие обратные вызовы:

onPause() → onStop()

Когда вы вернетесь к исходной активности

onRestart() → onStart() → onResume()

По той же причине, что и в onPause(), вы не хотите раздувать и прикреплять макет здесь.

Но что происходит с самой компоновкой, когда активность находится в задний план. Является ли макет еще прикрепленным?

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

Что произойдет, если пользователь прекратит действие, нажав кнопку Назад Кнопка

Предполагая, что метод onBackPressed() не переопределен для достижения пользовательского поведения (в этом случае он предназначен для захватов), вызывается onDestroy(), и действие уничтожается, и больше нет связанного с ним вида.

Что происходит, когда активность находится в фоновом режиме и в Android GC решает уничтожить деятельность и вернуть ресурсы?

В соответствии с жизненным циклом действия в документации будет вызываться onDestroy(). Но нет никакой гарантии этого. На этом этапе активность и связанное с ней представление просто собираются с мусором, и соединение отсутствует. В следующий раз, когда вы запустите приложение, onCreate() будет вызываться как обычно, и вы просто начинаете с начала снова.

Что происходит, когда я поворачиваю свое устройство?

Как работает Android, фактически уничтожить текущую активность и снова наполнить новый макет и снова начать с метода onCreate(). Так что технически происходит:

onPause() → onStop() → onDestroy() → onCreate() → onStart() → onResume()

Из-за этого вы можете даже иметь разный макет и просмотр в ландшафтном режиме.

EDIT: добавлена ​​взаимосвязь между действиями, фрагментами и представлениями Фрагмент представляет часть (или поведение) на экране. Фрагмент может быть сделан, чтобы занять весь экран или вы можете иметь несколько фрагментов внутри Activity. У фрагментов свой жизненный цикл, но он тесно связан с жизненным циклом активности хозяина (и выходит за рамки этого ответа). Поскольку мы конкретно говорим о взглядах, я ограничу этот ответ двумя интересующими нас способами:

  • onCreateView()
  • onViewCreated()

Методы вызываются в следующем порядке:

onAttach() → onCreate() → onCreateView() → onViewCreated()

Вы выполняете фактическую инфляцию макета внутри onCreateView(), а затем выполняете инициализацию внутри метода onViewCreated(). Результат метода onCreateView() используется Android для раздувания представления.

Итак, когда создается фрагмент, созданный в первую очередь Activity?

Существует два способа отображения фрагментов - один заключается в том, чтобы поместить их в макет xml активности (как и любой обычный виджет, где вместо имени виджета вы будете использовать полное имя пакета класса фрагмента) или вы можете сделать добавление, используя FragmentManager программно (что является предпочтительным методом).

Если вы определяли фрагмент в макете xml, вы должны знать, что фрагмент не может быть удален программно. Было бы трудно изменить это и повторно использовать это пространство экрана для других фрагментов. Также в этом случае представление привязывается и привязывается к активности. В этом случае вы раздуваете xml-макет Activity в методе onCreate() активности. Итак, теперь поток будет выглядеть примерно так:

onCreate() [Activity] → onAttach() [Fragment] → onCreate() [Фрагмент] → onCreateView() [Фрагмент] → onViewCreated() [Фрагмент] → onStart() [Activity] → onResume() [Activity] → onActivityCreated() [Fragment]

Итак, сначала создается представление фрагмента и привязывается к фрагменту до создания метода onStart() для операции.

Если фрагмент добавлен программно, если он добавлен в метод onCreate(), то он следует за тем же потоком. Его можно запустить в любом месте. Вам просто нужно заменить жизненный цикл фрагмента в рамках деятельности в соответствующем месте. Когда вы добавляете фрагменты программно, в то время как фрагмент размещается в действии, представление привязывается к действию. Когда фрагмент удаляется из активности, вызывается onDetach(), и представление больше не является частью Activity. Ресурсы, взятые фрагментом, могут быть освобождены.

Как насчет вложенных представлений, вложенных фрагментов и т.д.?

Во вложенных представлениях, например в одном контейнере макета внутри другого, правила родительского контейнера применяются к контейнеру с непосредственным дочерним элементом. Сначала родитель сначала инициализируется. Итак, для виджета внутри LinearLayout сначала создается родительский LinearLayout, за которым сразу следует ребенок. При уничтожении таких взглядов все происходит, когда родитель перестает существовать. Я не читал о какой-либо документации относительно порядка, в котором это может произойти. У Android GC могут быть правила, но я не уверен, что они где-то документированы.

У вас также могут быть вложенные фрагменты - в этом случае родительский фрагмент инициализируется до того, как будет создан дочерний фрагмент (и это имеет смысл, не так ли?). Когда родительский фрагмент перестает существовать, ребенок также перестанет существовать. Ребенок не может существовать без родителя, но вы можете иметь родителя без дочернего элемента.

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

Просматриваются ли измерения до их прикрепления или после?

Представления являются мерилом после их прикрепления. Вызов getMeausredWidth() или getMeasuredHeight() будет возвращать ноль до этого. Но то, что вы можете сделать, это вызвать neasure() непосредственно в представлении перед его присоединением и передать MeasureSpecs (я бы посоветовал вам больше узнать об этом в официальных документах), чтобы установить некоторые ограничения. Но этот вариант не является доказательством дурака, поскольку он зависит от родительской ViewGroup, обеспечивающей ее собственные ограничения, которые имеют более высокий приоритет. Чтобы просто ответить на ваш вопрос, взгляды измеряются после их прикрепления.

Как насчет использования addView() для добавления представления в ViewGroup вручную?

Это то же самое, что и вложенные представления. Ребенок существует только тогда, когда он добавлен, и это контролируется пользователем. Во вложенных представлениях, определенных в макете xml, дети раздуваются сразу после их родителя. Здесь контроль больше в руках пользователя. Когда родительский вид в этом случае уничтожен, он принимает дочерний вид с ним.

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