Санкт-Петербургский государственный университет
Опубликован: 24.10.2012 | Доступ: свободный | Студентов: 8636 / 1150 | Оценка: 4.00 / 4.00 | Длительность: 05:26:00
Специальности: Системный архитектор
Лекция 1:

Введение в разработку Android-приложений

1.6. Компоненты Android-приложения

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

Тем не менее, главным параметром Android-приложения является возможность использовать компоненты других приложений, если они дают на это соответствующие права. Допустим, нам нужен некий компонент с прокруткой для отображения текста, и похожий компонент уже реализован в другом приложении. Тогда у нас есть возможность использовать реализованный компонент. В этом случае наше приложение не копирует необходимый код к себе и не создает ссылку на него. Вместо этого приложение делает запрос на исполнение части кода другого приложения, где есть нужный нам компонент.

В Android существует четыре типа компонентов: Activities, Services, Broadcast receivers и Content providers.

Также важно отметить объекты Intents, в Android-приложениях почти все работает благодаря им. Intent – это механизм для описания одной операции (выбрать фотографию, отправить письмо, сделать звонок, запустить браузер и перейти по указанному адресу и другие). Наиболее распространенный сценарий использования Intent – запуск другого Activity в своем приложении.

1.6.1. Activities

Activity представляет собой пользовательский интерфейс для одного действия, которое пользователь может совершить. Например, приложение для обмена текстовыми сообщениями может иметь одно Activity для отображения списка контактов, другое – для написания сообщения выбранному контакту, третье – для просмотра сообщений и еще одно для изменения настроек. Все эти Activities формируют единый пользовательский интерфейс, но не зависят друг от друга.

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

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

Activity может находиться в одном из трех состояний:

  • Active или Running – находится на переднем плане и имеет фокус для взаимодействия с пользователем.
  • Paused – потеряло фокус, но все еще видно пользователю. Сверху находится другое Activity, которое или прозрачно или закрывает не весь экран. Приостановленное Activity полностью "живое" (его состояние сохранено), но может быть уничтожено системой в случае нехватки памяти.
  • Stopped – полностью перекрыто другим Activity. Оно больше не видно пользователю и будет уничтожено системой, когда понадобится память.

Если Activity приостановлено или остановлено, система может удалить его из памяти, либо послать запрос на его завершение, или просто уничтожить его процесс. Когда Activity снова отображается пользователю, его состояние полностью восстанавливается.

Переходя от состояния к состоянию, Activity уведомляет об этом, вызывая следующие методы:

  • void onCreate()
  • void onStart()
  • void onRestart()
  • void onResume()
  • void onPause()
  • void onStop()
  • void onDestroy()

Жизненный цикл Activity состоит из трех вложенных циклов (Рис. 1.3):

  • Жизненный цикл activity начинается с вызова метода onCreate(), в котором производится первоначальная настройка глобального состояния, и завершается вызовом метода onDestroy(), в котором оно освобождает занятые ресурсы.
  • Видимая часть жизненного цикла происходит между вызовами onStart() и onStop(). В течение этого времени пользователь может видеть Activity на экране, хотя оно может быть не на переднем плане и не взаимодействовать с пользователем. Методы onStart() и onStop() могут вызываться столько раз, сколько Activity становится видимым или скрытым для пользователя.
  • На переднем плане Activity находится между вызовами onResume() и onPause(). В течение этого времени Activity находится поверх других и взаимодействует с пользователем. Activity может часто переходить в состояние паузы и выходить из него. Например, метод onPause() может быть вызван, когда устройство переходит в спящий режим или когда запускается другое Activity, а метод onResume() – при получении результата от закрывающегося Activity.
Жизненный цикл Activity

Рис. 1.3. Жизненный цикл Activity

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

Метод Описание Может ли быть уничтожен? Следующий метод
onCreate() Вызывается один раз, при создании Activity. Здесь должна производиться первоначальная настройка – создание экземпляров класса View (пользовательский интерфейс), запись данных в списки и так далее.

За ним всегда следует вызов метода onStart().

нет onStart()
onStart() Вызывается после того как Activity было остановлено и теперь снова запускается.

За ним всегда следует вызов onResume()

нет onResume()
onRestart() Вызывается перед тем как Activity становится видимым для пользователя.

За ним следует вызов onResume(), если Activity переходит на передний план, или onStop(), если оно скрывается.

нет onResume()

или

onStop()

onResume() Вызывается перед тем, как Activity начинает взаимодействовать с пользователем. С этого момента Activity находится на вершине стека и принимает весь пользовательский ввод.

За ним следует вызов onPause().

нет onPause()
onPause() Вызывается системой перед возобновлением другого Activity. Этот метод обычно используется для сохранения измененных данных, остановки анимации и других вещей, которые могут потреблять процессорное время. Другое Activity не будет возобновлено, пока он не завершится.

За ним может быть вызван метод onResume() если Activity возвращается на передний план, или метод onStop(), если оно становится невидимым для пользователя.

да onResume()

или

onStop()

onStop() Вызывается когда Activity больше не видно пользователю. Это может происходить потому, что оно уничтожается или потому, что другое Activity было возобновлено и перекрыло его.

Затем может быть вызван либо метод onRestart(), если Activity возвращается для взаимодействия с пользователем, либо метод onDestroy(), если оно завершается.

да onRestart()

или

onDestroy()

onDestroy() Вызывается перед уничтожением Activity. Это последний вызов, который оно получит. Может быть вызван либо потому, что Activity завершается (кто-то вызвал метод finish()), либо потому, что система временно уничтожает этот экземпляр для экономии памяти. да нет
Обратите внимание на колонку "Может ли быть уничтожен?". Она указывает на то, может ли система уничтожить процесс, в котором запущено Activity, в любой момент после возврата из этого метода, не выполняя больше ни одной строчки кода Activity. Три метода: OnPause(), OnStop() и OnDestroy() – отмечены "Да". Но только метод OnPause() будет гарантированно вызван перед уничтожением процесса, поскольку он первый в этом списке, а OnStop() и OnDestroy() могут не вызываться. Поэтому для сохранения измененных данных нужно использовать метод OnPause(). Методы, отмеченные "Нет", защищают процесс, в котором запущено Activity, от уничтожения с момента их вызова.

1.6.2. Типы процессов в Android-приложении

Жизненный цикл приложения тесно связан с жизненным циклом его процесса. Также он зависит от текущего состояния системы. В случае нехватки памяти, Android убивает наименее значимые процессы. Значимость процесса зависит от его типа. Типы процессов, в зависимости от важности, выглядят следующим образом (от наиболее до наименее важных):

  • Процесс переднего плана – процесс приложения, с которым пользователь взаимодействует в данный момент. Процесс считается таковым, если его Activity находится на вершине Activity-стека (была вызвана функция onResume(), или его Broadcast Receiver работает в настоящее время (в данный момент исполняется приложением onReceive()), или же его Service выполняет callback-методы, такие как onCreate(), onStart() или onDestroy(). Как правило, таких процессов очень мало и они закрываются в самую последнюю очередь.
  • Видимый процесс — процесс, который имеет Activity, видимый конечному пользователю в данный момент времени. Процессов, которые выводятся на экран, очень мало, поэтому их работа прерывается только в крайнем случае, если не хватает ресурсов для активных приложений.
  • Служебный процесс – процесс, содержащий Service, для которого была вызвана функция startService(), при условии, что данный Service сейчас работает.
  • Процесс заднего фона. Данный процесс не имеет видимых пользователю Activity (была вызвана функция onStop()). Как правило, существует множество фоновых процессов, работа которых завершается по принципу "последний запущенный закрывается последним", чтобы освободить ресурсы для приложений, работающих на переднем плане.

1.6.3. Services

Service – это некий процесс, который запускается в фоновом режиме. Как пример, Service может получать данные по сети, выполнять какие-либо длительные вычисления. Хорошим примером Service служит проигрыватель музыки. Пользователь может выбрать любую песню в проигрывателе, включить ее и закрыть плеер занявшись чем-нибудь другим. Музыка будет проигрываться в фоновом процессе. Service проигрывания музыки будет работать, даже если Activity плеера закрыта.

Подобно Activity, Service имеет свои методы жизненного цикла:

  • void onCreate()
  • void onStart(Intent intent)
  • void onDestroy()

В полном жизненном цикле Service существует два вложенных цикла:

  • полная целая жизнь Service – промежуток между временем вызова метода onCreate() и временем возвращения onDestroy(). Подобно Activity, для Services производят начальную инициализацию в onCreate() и освобождают все остающиеся ресурсы в onDestroy();
  • активная целая жизнь Service – начинается с вызова метода onStart(). Этому методу передается объект Intent, который передавался в startService().

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

1.6.4. Broadcast receivers

Broadcast receiver – это компонент, который ничего не делает, кроме того, что рассылает и реагирует на широковещательные сообщения. Примером широковещательных компонентов могут быть: сообщения об переходе на летнее/зимнее время, сообщения об минимальном заряде батареи и так далее.

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

Приемник широковещательных сообщений имеет единственный метод жизненного цикла: onReceive(). Когда широковещательное сообщение прибывает для получателя, Android вызывает его методом onReceive() и передает в него объект Intent, содержащий сообщение. Приемник широковещательных сообщений является активным только во время выполнения этого метода. Процесс, который в настоящее время выполняет Broadcast receiver, является приоритетным процессом и будет сохранен, кроме случаев критического недостатка памяти в системе.

Когда программа возвращается из onReceive(), приемник становится неактивным и система полагает, что работа объекта Broadcast receiver закончена. Процесс с активным широковещательным получателем защищен от уничтожения системой. Однако процесс, содержащий неактивные компоненты, может быть уничтожен системой в любое время, когда память, которую он потребляет, будет необходима другим процессам.

1.6.5. Content providers

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

Несипбай Сагыныш
Несипбай Сагыныш
Сергей Петров
Сергей Петров