1. Activity и жизненный цикл: Основы взаимодействия с пользователем
Activity и жизненный цикл: Основы взаимодействия с пользователем
Добро пожаловать в курс «Базовые компоненты Android: Фундамент разработки». Мы начинаем наше погружение в мир мобильной разработки с самого главного, самого заметного и фундаментального компонента любого Android-приложения — Activity (Активити).
Если вы когда-либо открывали приложение на своем смартфоне, вы уже взаимодействовали с Activity. В этой статье мы разберем, что это такое, как оно работает «под капотом» и почему понимание его жизненного цикла отличает профессионального разработчика от новичка.
Что такое Activity?
В самом простом понимании, Activity — это один экран вашего приложения. Это контейнер для пользовательского интерфейса (UI), с которым взаимодействует человек.
Представьте себе приложение «Контакты».
Хотя они работают вместе, создавая ощущение единого приложения, технически это независимые компоненты, которые запускают друг друга.
> Activity — это компонент приложения, который предоставляет экран, с которым пользователи могут взаимодействовать для выполнения чего-либо: набора номера, съемки фото, отправки письма или просмотра карты.
Роль Activity в архитектуре Android
В отличие от программ на языках C или Java, которые обычно начинают выполнение с метода main(), система Android инициализирует код в экземпляре Activity, вызывая специфические методы обратного вызова (callbacks), соответствующие определенным этапам ее жизненного цикла.
Каждая Activity должна быть объявлена в файле манифеста приложения (AndroidManifest.xml). Если вы создадите файл класса Activity, но забудете добавить запись о нем в манифест, система не сможет запустить этот экран и приложение упадет с ошибкой.
Пример объявления в манифесте:
Здесь фильтр намерений (intent-filter) с категорией LAUNCHER говорит системе, что именно эта Activity является точкой входа в приложение (появляется при нажатии на иконку в меню телефона).
Жизненный цикл Activity
Понимание жизненного цикла — это «таблица умножения» для Android-разработчика. Activity не просто существует; она рождается, живет, уходит на второй план и умирает. В каждый из этих моментов система вызывает специальные методы, которые вы можете переопределить, чтобы выполнить нужные действия.
Зачем это нужно? Представьте, что пользователь смотрит видео в вашем приложении, а затем ему звонят. Ваше приложение должно:
Без управления жизненным циклом ваше приложение будет потреблять батарею, терять данные пользователя и вылетать.
!Диаграмма переходов состояний жизненного цикла Activity от создания до уничтожения.
Основные состояния и методы
Рассмотрим каждый этап подробно, следуя хронологии жизни Activity.
#### 1. onCreate() — Рождение
Это первый метод, который вызывается при создании Activity. Он срабатывает только один раз за весь цикл жизни экземпляра.
Что здесь делать:
* Инициализировать UI (вызвать setContentView).
* Создавать переменные и объекты.
* Привязывать данные к спискам.
Обратите внимание на параметр savedInstanceState. Если Activity пересоздается (например, после поворота экрана), этот объект содержит данные, которые вы сохранили перед уничтожением. Если Activity запускается впервые, он равен null.
#### 2. onStart() — Появление
Метод вызывается, когда Activity становится видимой пользователю. Однако, взаимодействовать с ней пока нельзя. Она как бы «проявляется» на экране.
Что здесь делать: * Запускать анимации, которые должны быть видны сразу при появлении. * Регистрировать широковещательные приемники (BroadcastReceivers), которые нужны только когда экран виден.
#### 3. onResume() — Активность
Сразу после onStart() вызывается onResume(). В этот момент Activity находится на переднем плане, и пользователь может нажимать кнопки, вводить текст и скроллить. Activity переходит в состояние «Resumed» (Возобновлено).
Важно: Activity остается в этом состоянии до тех пор, пока что-то не переключит фокус (например, входящий звонок, переход на другой экран или выключение экрана).
Что здесь делать: * Запускать воспроизведение видео или аудио. * Запускать обновление данных с датчиков (GPS, акселерометр).
#### 4. onPause() — Потеря фокуса
Этот метод вызывается, когда пользователь начинает покидать Activity или она перекрывается другим окном (например, полупрозрачным диалогом), но всё ещё частично видна.
Что здесь делать: * Остановить анимации или видео, чтобы не тратить процессорное время. * Сохранить черновик сообщения, если пользователь начал его писать. * Нельзя: Выполнять тяжелые операции (сохранение в базу данных, сетевые запросы), так как это заблокирует переход к следующему экрану.
#### 5. onStop() — Исчезновение
Когда Activity больше не видна пользователю (полностью перекрыта другой Activity или приложение свернуто), вызывается onStop().
Что здесь делать: * Освобождать тяжелые ресурсы, которые не нужны, пока пользователь не видит экран. * Сохранять данные в базу данных (SQLite, Room) или настройки. * Останавливать тяжелые вычисления.
#### 6. onDestroy() — Уничтожение
Последний вызов перед тем, как Activity будет полностью удалена из памяти. Это может произойти, если пользователь нажал кнопку «Назад» (Back) или если система решила убить процесс для освобождения памяти.
Что здесь делать: * Окончательная очистка ресурсов (закрытие соединений, отписка от всех событий).
#### 7. onRestart() — Перезапуск
Этот метод вызывается только в одном случае: если Activity была остановлена (onStop()), но не уничтожена, и пользователь снова вернулся к ней. Сразу за ним последует onStart().
Сводная таблица методов
| Метод | Описание | Следующий метод |
| :--- | :--- | :--- |
| onCreate() | Создание Activity. Инициализация. | onStart() |
| onStart() | Activity становится видимой. | onResume() |
| onResume() | Activity готова к взаимодействию. | onPause() |
| onPause() | Activity теряет фокус, но может быть видна. | onStop() или onResume() |
| onStop() | Activity больше не видна. | onDestroy() или onRestart() |
| onRestart() | Возврат к Activity после onStop(). | onStart() |
| onDestroy() | Полное уничтожение Activity. | Нет |
Стек Activity (Back Stack)
Android управляет навигацией между экранами с помощью структуры данных, называемой стек (или Back Stack). Это работает по принципу LIFO (Last In, First Out — «последним пришел, первым ушел»).
!Визуализация стека задач (Back Stack), показывающая принцип наслоения Activity друг на друга.
onStop), но сохраняется в стеке.onDestroy) и выкидывается из стека.onRestart -> onStart -> onResume) и снова показывается пользователю.Если пользователь будет нажимать «Назад» до тех пор, пока стек не опустеет, приложение закроется, и пользователь вернется на домашний экран (Launcher).
Проблема поворота экрана
Одна из самых частых проблем новичков — поведение Activity при повороте устройства.
По умолчанию, при изменении конфигурации (поворот экрана, смена языка, подключение клавиатуры) система уничтожает текущую Activity и создает её заново.
Это происходит следующим образом:
onPause()onStop()onDestroy()onCreate() (новый экземпляр)onStart()onResume()Почему так сделано?
Это позволяет приложению автоматически загрузить альтернативные ресурсы. Например, у вас может быть отдельный макет (layout) для горизонтальной ориентации (layout-land), где кнопки расположены иначе. Система перезапускает Activity, чтобы применить этот новый макет.
Последствия: Если вы хранили какие-то данные в обычных переменных класса Activity (например, счетчик нажатий), они сбросятся к значениям по умолчанию, так как старый объект класса был удален, а новый создан с нуля.
Для решения этой проблемы используются:
* Метод onSaveInstanceState(outState: Bundle) для сохранения небольших данных.
* Архитектурный компонент ViewModel (который мы изучим в следующих модулях курса) для сохранения сложных данных.
Практические советы
super: При переопределении любого метода жизненного цикла (например, onCreate), первой строкой всегда должен быть вызов метода родительского класса: super.onCreate(savedInstanceState). Иначе вы получите исключение SuperNotCalledException.onCreate код, который скачивает файл из интернета в течение 5 секунд, ваше приложение «зависнет» на 5 секунд, и система предложит пользователю закрыть его (ошибка ANR — Application Not Responding).onStart, освободите его в onStop. Если в onResume — освободите в onPause.Заключение
Activity — это фундамент, на котором строится взаимодействие пользователя с вашим приложением. Понимание того, в каком состоянии находится ваш экран (создается, виден, скрыт или уничтожается), позволяет писать стабильные и предсказуемые приложения.
В следующих статьях мы углубимся в создание пользовательского интерфейса внутри Activity и научимся передавать данные между разными экранами.