Добавлен: 29.10.2018
Просмотров: 48051
Скачиваний: 190
10.8. Android
901
входа должна быть определена активность. Приложение выполняет код в своей актив-
ности, отвечающей за взаимодействие с пользователем.
Пример манифеста почтового приложения, показанный в листинге 10.5, содержит две
активности. Первая является основным интерфейсом пользователя почты, позволяю-
щим пользователям просматривать сообщения, а вторая — отдельным интерфейсом для
составления нового сообщения. Первая активность почтовой программы объявлена для
приложения в качестве основной точки входа, то есть той самой активности, которая
стартует при запуске пользователем приложения с главного экрана.
Поскольку первая активность является главной, она будет показана пользователю
в виде приложения, которое он может запустить из основной программы запуска при-
ложений. Если приложение будет запущено, система войдет в состояние, показанное
на рис. 10.32. Здесь диспетчер активностей, показанный в левой части рисунка, создал
в своем процессе для отслеживания активности внутренний экземпляр ActivityRecord.
Одна или несколько таких активностей сведены в контейнеры, которые называются
задачами и примерно соответствуют тому, что воспринимается пользователем как
приложение. В данный момент диспетчер активностей запустил процесс почтового
приложения и экземпляр его MainMailActivity для отображения главного пользова-
тельского интерфейса приложения, который связан с соответствующим экземпляром
ActivityRecord. Эта активность находится в состоянии, называемом «возобновленная»
(resumed), поскольку теперь она находится на первом плане пользовательского ин-
терфейса.
Диспетчер активностей в процессе system_server
Процесс почтового приложения
MailMainActivity
Задача: Email
ActivityRecord
(MailMainActivity)
ВОЗОБНОВ-
ЛЕННАЯ
Рис. 10.32. Начало работы основной активности почтового приложения
Если теперь пользователь переключится из почтового приложения (не выходя из него)
и запустит приложение камеры, чтобы сделать снимок, мы окажемся в состоянии, по-
казанном на рис. 10.33. Заметьте, что у нас теперь есть новый процесс камеры, запустив-
ший основную активность, и связанный с ним экземпляр ActivityRecord в диспетчере
активностей, и теперь это возобновленная активность. Кое-что интересное происходит
и с прежней почтовой активностью: теперь вместо состояния «возобновленная» она
получила состояние «остановленная» (stopped) и сохраненное состояние активности
хранится в ActivityRecord.
Когда активность уходит с первого плана, система требует от нее сохранить ее состоя-
ние. Это приводит к тому, что приложение создает минимальный объем информации
о состоянии, отображающей то, что пользователь видит в данный момент, возвращает
эти сведения диспетчеру активности и сохраняет их в процессе system_server, в экзем-
пляре ActivityRecord, связанном с этой активностью. Это сохраненное для активности
902
Глава 10. Изучение конкретных примеров: Unix, Linux и Android
Процесс почтового приложения
MailMainActivity
CameraMainActivity
Задача: Camera
ActivityRecord
(CameraMainActivity)
ActivityRecord
(MailMainActivity)
Задача: Email
Диспетчер активностей
в процессе system_server
Процесс приложения камеры
Сохраненное
состояние
ВОЗОБНОВ-
ЛЕННАЯ
ОСТ
АНОВ-
ЛЕННАЯ
Рис. 10.33. Начало работы приложения камеры после почтовой программы
состояние, как правило, невелико и содержит, к примеру, сведения о том, на каком этапе
вы остановили прокрутку почтового сообщения, но не само сообщение, которое будет
сохранено приложением где-то в его постоянном хранилище.
Вспомним, что хотя операционная система Android нуждается в страничной подкачке
файлов (она может загружать и выгружать неизмененную оперативную память, на
которую были отображены файлы на диске, например, с кодом), она не основана на
использовании подкачки. Это означает, что все измененные страницы оперативной
памяти в процессе, принадлежащем приложению, должны оставаться в оперативной
памяти. То, что состояние основной активности почтового приложения надежно со-
хранено вне этого приложения в диспетчере активностей, возвращает системе некую
гибкость в работе с памятью, которую предоставляет подкачка.
Например, если приложение камеры начинает требовать большой объем оперативной
памяти, система может просто избавиться от почтового процесса (рис. 10.34). Экзем-
пляр ActivityRecord с его ранее сохраненным состоянием остается надежно спрятанным
диспетчером активностей в процессе system_server. Поскольку процесс system_server
является хозяином всех основных системных служб Android, он должен всегда оста-
ваться работающим, поэтому сохраненное здесь состояние будет оставаться неизмен-
ным до того времени, когда надобность в нем минует.
Наше взятое для примера почтовое приложение не только имеет активность для
своего основного пользовательского интерфейса, но и включает другую активность —
ComposeActivity. Приложения могут объявить любое нужное количество активностей.
Это не только может помочь в организации реализации приложения, но и, что более
важно, может использоваться для реализации взаимодействия между приложениями.
Например, это положено в основу имеющейся в Android системы общего использо-
вания приложениями друг друга, участие в которой принимает представленная здесь
ComposeActivity. Если пользователь, работая с приложением камеры, решит, что ему
следует поделиться сделанным фотоснимком, одним из находящихся в его распоря-
жении вариантов является ComposeActivity. Если будет выбран этот вариант, то данная
10.8. Android
903
CameraMainActivity
ActivityRecord
(CameraMainActivity)
ActivityRecord
(MailMainActivity)
Задача: Camera
Задача: Email
Диспетчер активностей
в процессе system_server
Процесс приложения камеры
Сохраненное
состояние
ВОЗОБНОВ-
ЛЕННАЯ
ОСТ
АНОВ-
ЛЕННАЯ
Рис. 10.34. Удаление почтового процесса для возвращения оперативной памяти
и предоставления ее камере
активность будет запущена и сделанный снимок станет общим достоянием. (Позже мы
увидим, как приложение камеры может найти ComposeActivity почтового приложения.)
Реализация этого варианта, дающего возможность поделиться снимком при состоянии
активности, показанном на рис. 10.34, приведет к новому состоянию, показанному на
рис. 10.35. При этом есть ряд важных моментов, о которых стоит упомянуть:
1. Процесс почтового приложения должен быть снова запущен, чтобы выполнить
свою активность ComposeActivity.
2. Но в этот момент старая активность MailMainActivity запущена не будет, поскольку
в ней нет необходимости. Таким образом будет сокращен объем задействуемой
оперативной памяти.
3. Теперь у задачи Camera две записи: исходная CameraMainActivity, в которой мы
только что были, и новая ComposeActivity, которая теперь показана на рисунке. Для
пользователя все это выглядит как единая задача: это камера, в данный момент
взаимодействующая с ним, чтобы отправить снимок по электронной почте.
4. Новая ComposeActivity показана на самом верху, следовательно, она является
возоб новленной. Предыдущая CameraMainActivity теперь больше не на самом
верху, поэтому ее состояние было сохранено. В этот момент мы может совершенно
безопасно завершить ее процесс, если занимаемая ею оперативная память пона-
добится для чего-то другого.
И наконец, давайте посмотрим, что получится, если пользователь вернется к задаче
Camera, находясь в этом последнем состоянии (то есть составляя почтовое сообщение,
чтобы поделиться снимком) и вернувшись к почтовому приложению. На рис. 10.36
показано новое состояние, в котором окажется система. Учтите, что мы вернули за-
дачу Email с ее основной активностью на первый план. Тем самым MailMainActivity
стала активностью первого плана, но в данный момент у нас нет экземпляра ее запуска
в процессе приложения.
904
Глава 10. Изучение конкретных примеров: Unix, Linux и Android
ActivityRecord
(ComposeActivity)
ActivityRecord
(CameraMainActivity)
ActivityRecord
(MailMainActivity)
ComposeActivity
CameraMainActivity
Процесс почтового приложения
Задача: Camera
Задача: Email
Диспетчер активностей
в процессе system_server
Процесс приложения камеры
Сохраненное
состояние
ОСТ
АНОВ-
ЛЕННАЯ
ВОЗОБНОВ-
ЛЕННАЯ
ОСТ
АНОВ-
ЛЕННАЯ
Сохраненное
состояние
Рис. 10.35. Реализация возможности поделиться снимком камеры
через почтовое приложение
MailMainActivity
ComposeActivity
CameraMainActivity
ActivityRecord
(MailMainActivity)
ActivityRecord
(ComposeActivity)
ActivityRecord
(CameraMainActivity)
Процесс почтового приложения
Задача: Camera
Задача: Email
Диспетчер активностей
в процессе system_server
Процесс приложения камеры
ОСТ
АНОВ-
ЛЕННАЯ
ВОЗОБНОВ-
ЛЕННАЯ
ОСТ
АНОВ-
ЛЕННАЯ
Сохраненное
состояние
Сохраненное
состояние
Рис. 10.36. Возвращение к почтовому приложению
10.8. Android
905
Для возвращения к предыдущей активности система создает новый экземпляр, передавая
ему ранее сохраненное состояние, предоставленное старым экземпляром. Это действие
по восстановлению активности из его сохраненного состояния должно быть способно
вернуть активность в то же самое визуальное состояние, в котором пользователь ее по-
кинул. Для выполнения этой задачи приложение должно заглянуть в свое сохраненное
состояние, чтобы получить сообщение о том, где был пользователь, загрузить данные это-
го сообщения из своего постоянного хранилища, затем применить любую позицию про-
крутки или другое состояние пользовательского интерфейса, которое было сохранено.
Службы
Служба
(service) имеет две отличительные особенности:
1. Она должна быть самодостаточной фоновой операцией, запускаемой на продол-
жительный срок. Широко распространенными примерами использования служб
таким способом являются фоновое проигрывание музыки, поддержка активного
сетевого подключения (например, с помощью IRC-сервера) в то время, когда
пользователь работает с другими приложениями, загружает или выгружает данные
в фоновом режиме, и т. д.
2. Она может работать как точка связи для других приложений или систем, целью
которой является выполнение сложных видов взаимодействия с приложением.
Это может быть использовано приложениями для предоставления безопасных
API-функций другим приложениям: например, предоставления обработки изо-
бражений или аудиоданных, текста для его озвучивания и т. д.
Пример манифеста почтового приложения, показанный в листинге 10.5, содержит
службу, которая используется для синхронизации почтового ящика пользователя.
Обычная реализация будет планировать запуск службы через определенные про-
межутки времени, например каждые 15 минут, запуская службу в намеченный срок
и самостоятельно останавливая ее, когда она выполнит свою работу.
Это типичное использование первой разновидности службы — запущенной на длитель-
ный срок фоновой операции. На рис. 10.37 показано состояние системы в этот момент,
которое не отличается особой сложностью. Диспетчер активностей создал ServiceRecord,
чтобы отслеживать службу, отмечая, что она была запущена и создала таким образом
свой экземпляр SyncService в процессе приложения. В этом состоянии служба полно-
стью активна (за исключением того случая, когда вся система собирается погрузиться
в сон, если не удерживает блокировку сна) и вольна делать все что ей угодно. Возможно,
пока сохраняется это состояние, процесс приложения уйдет в небытие, например, по-
терпев аварию, но диспетчер активности продолжит обслуживание своего экземпляра
ServiceRecord и может в такой ситуации, если потребуется, перезапустить службу.
SyncService
ServiceRecord
(SyncService)
Процесс почтового приложения
Диспетчер активностей
в процессе system_server
ОСТ
АНОВ-
ЛЕННАЯ
Рис. 10.37. Запуск прикладной службы