Найти в Дзене

Жизненный цикл Активити

В различных компонентах есть свои жизненные циклы. И система нас уведомляет о том, что происходит, например, с активити и какая сейчас стадия, чтобы мы смогли оперативно среагировать. Что это вообще значит? В активити и всех его подклассах есть набор методов (callback), которые можно использовать при изменении состояния активити. Эти методы можно переопределить. Зачем они нужны? Например, чтобы мы могли менять какое-то поведение, если, например, активити не видима. Когда наше приложение свернуто или пользователь отвлекся на звонок и приложение не видно, то было бы логично в этот момент поставить видео на паузу, остановить анимацию и т.п. Вот те методы как раз ловят такие моменты и там можно прописать, что нужно сделать. Звучит удобно. На картинках ниже описаны состояния активити и фрагмента и основные методы, которые вы будете использовать. Заметьте, что они очень похожи. Что в целом может быть с активити: Состояния жизненного цикла. Они общие для фрагмента и активити: И сами методы: o

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

В активити и всех его подклассах есть набор методов (callback), которые можно использовать при изменении состояния активити. Эти методы можно переопределить. Зачем они нужны? Например, чтобы мы могли менять какое-то поведение, если, например, активити не видима. Когда наше приложение свернуто или пользователь отвлекся на звонок и приложение не видно, то было бы логично в этот момент поставить видео на паузу, остановить анимацию и т.п. Вот те методы как раз ловят такие моменты и там можно прописать, что нужно сделать. Звучит удобно.

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

Что в целом может быть с активити:

  1. Она может быть видима. Всё, что между onStart и onStop (два зеленых прямоугольника).
  2. В фокусе. Это когда пользователь может как-то взаимодействовать (кликать на кнопки, вводить текст, свайпать и т.п.)
  3. Foreground — когда активити на экране.
  4. Background. Активити не на экране и мы её не видим. Например, пользователь ушел в другое приложение или выключил экран.

Состояния жизненного цикла. Они общие для фрагмента и активити:

  1. Initialized — Стартовое состояние, когда создается новая активити. Отсюда сразу же переходит ко второму состоянию.
  2. Created — Активити создана, но все еще не видима и пользователь никак не может взаимодействовать с ней.
  3. Started — Активити уже видна, но все еще не в фокусе.
  4. Resumed — Все видно и в фокусе. Полностью рабочее и пользователь может взаимодействовать.
  5. Destroyed — Активити уничтожена. Теперь она может быть удалена из памяти в любой момент, поэтому на нее нельзя ссылаться и как-то взаимодействовать.

И сами методы:

onCreate — Вызывается первым, когда активити стартует. Появление этого метода означает, что активити создана и проинициализирована. Он вызывается всего один раз за весь жизненный цикл. Тут мы можем проинициализировать какой-то ui, переменные и сделать что-то еще, что должно делаться только один раз за весь жизненный цикл. Помните, что тут активити еще не видна и не в фокусе.

onStart — метод срабатывает, когда активити вот-вот станет видимой. Этот метод срабатывает несколько раз. Например, когда пользователь переходит на другой экран, а потом возвращается. Активити все еще не в фокусе и не видима. Тут мы можем запускать любые штуки, которые должны запускаться, когда активити становится видима. Например, анимация.

onResume — срабатывает, когда активити в фокусе и пользователь может с ней взаимодействовать. Соответственно, тут мы запускаем что-то, что должно работать, когда появляется фокус. Как вариант: всё та же анимация.

onPause — парный метод для onResume. Вызывается, когда теряется фокус. Например, появился какой-то диалог или системное сообщение. Сейчас пользователь не может взаимодействовать с активити. Тут можно что-то останавливать, что не должно работать, когда нет фокуса. ВАЖНО: если что-то делаем тут, то оно должно быть моментальным, потому что следующая активити не откроется, пока не завершится метод. Будет неприятно, что вы нажимаете кнопку для перехода — должен открыться экран — а приложение думает несколько секунд, потому что вы сделали какое-то сохранение данных в onPause + кучу остановок.

onStop — парный метод для onStart. Вызывается, когда активити больше не видна. Тут останавливаем всё, что не должно выполняться, когда активити не на экране. Например, останавливаем анимацию, видео, и любую логику для ui. Не нужно тратить ресурсы впустую, когда пользователь не смотрит. Плюс помним про фоновые ограничения. Также тут можем сохранить какие-то данные, если надо.

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

Во фрагментах примерно всё такое же. Посмотрим на основные различия.

onAttach — вызывается, когда фрагмент присоединяется к активити. Вызывается только один раз.

onCreate — все как в активити. Фрагмент создан. Но не инициализируйте тут xml. Это надо делать в onCreateView, когда система начинает рисовать фрагмент. Тут можно делать что-то, что не связано с ui. Например, проинициализировать адаптер.

onCreateView — вызывается между onCreate и onViewCreated. Тут система впервые рисует фрагмент, когда он становится видимым. Тут мы как раз и присоединяем xml. Здесь возвращается вью, если у нашего фрагмента есть какой-то ui.

onViewCreated — вызывается сразу после прошлого. Но, если раньше мы сохраняли какое-то состояние для фрагмента, то тут про него еще ничего не известно. Тут можно привязать какую-то логику к вьюшкам, потому что они уже гарантировано проинициализированы.

onStart — вызывается перед тем, как фрагмент станет видимым.

onResume — вызывается, когда активити возобновляет фрагмент. Тут фрагмент видим, в фокусе и работает.

onStop — все как у активити. Вызывается, когда пользователь уходит с фрагмента. Тут можно, например, сохранить какое-то состояние.

onDestroyView — в отличии от активити, во фрагменте вью уничтожаются каждый раз, когда они не видны. Вызывается после того, как вью больше не видно. Соответственно, не надо обращаться к вью, потому что они уже уничтожены.

onDetach — вызывается, когда связь между активити и фрагментом уничтожена.

Кстати, onActivityCreated во фрагментах теперь устарел. Вместо него надо использовать onViewCreated, если касается вью или onCreate, если другая инициализация.

Полезные заметки:

onSaveInstanceState не вызывается, если мы вызываем finish() и нажимаем назад. Потому что активити уничтожена.

Когда переходим в onStop, система использует onSaveInstanceState, чтобы сохранить состояние приложение, если придется его убить. Например, если мы свернули приложение, а системе пришлось убить процесс, то когда мы откроем бэкстек с приложениями, то убитое приложение все равно будет видно. Система его самостоятельно постарается восстановить. Вышло и так много текста, так что это проверю в следующей статье. :)