Файл: Debian Таненбаум Бос.pdf

ВУЗ: Не указан

Категория: Книга

Дисциплина: Операционные системы

Добавлен: 29.10.2018

Просмотров: 48038

Скачиваний: 190

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

916  

 Глава 10. Изучение конкретных примеров: Unix, Linux и Android 

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

Диспетчер активностей 

в процессе system_server

Процесс приложения камеры

Предоставленные URI

Задача: Pictures

ОТПРАВКА

content://pics/1

Сохраненное 
состояние

ActivityRecord

(ComposeActivity)

ActivityRecord

(CameraActivity)

Для: ComposeActivity

URI: content://pics/1

Разре-
шено

Про
верка

PicturesProvider

Полномочия: «pics»

ComposeActivity

Процесс почтового приложения

Открыть

content://pics/1

Получить 
данные

ВОЗОБНОВ-

ЛЕННАЯ

ОСТ

АНОВ-

ЛЕННАЯ

Рис. 10.43. Реализация возможности поделиться снимком с использованием 

поставщика контента

Новое развитие ситуации показано на рис. 10.44. Оно почти идентично тому, что было 
показано на рис. 10.43, единственным отличием является способ объединения актив-
ностей двух приложений, когда почтовое приложение запускает соответствующую 
активность по выбору снимка в приложении камеры. После выбора снимка его URI 
возвращается почтовому приложению, и в этот момент наше предоставление URI за-
писывается диспетчером активностей.

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

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


background image

10.8. Android   

917

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

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

Настройки системы Android включают пользовательский интерфейс для выбора ме-
тодов ввода. Этот интерфейс показывает все доступные методы ввода установленных 
на данный момент приложений и то, включены они или нет. Если пользователь хочет 
воспользоваться новым методом ввода после установки его приложения, он должен 
зайти в интерфейс настройки системы и включить этот метод. При этом система так-
же может проинформировать пользователя, какие именно действия будет разрешено 
совершать приложению.

Диспетчер активностей 

в процессе system_server

Процесс приложения камеры

PicturesProvider

Полномочия: «pics»

ComposeActivity 

Процесс почтового приложения

Предоставленные URI

Разре-
шено

Про-
верка

Открыть

content://pics/1 

Получить 
данные

Для: ComposeActivity
URI: content://pics/1 

Задача: Pictures

ActivityRecord

(PicturePickerActivity) 

ActivityRecord

(ComposeActivity) 

Сохраненное
состояние

 

ПРИЕМ

content://pics/1 

ПОЛУЧЕНИЕ

ВОЗОБНОВ-

ЛЕННАЯ

ОСТ

АНОВ-

ЛЕННАЯ

Рис. 10.44. Добавление возможности прикрепить снимок с использованием 

поставщика контента

Даже если приложение включено в качестве метода ввода, для ограничения его влия-
ния в Android используются тонко выверенные технологии контроля доступа. Напри-
мер, фактически только приложение, использующееся в качестве текущего метода вво-
да, может иметь любую специальную итерацию. Если пользователь включил несколько 


background image

918  

 Глава 10. Изучение конкретных примеров: Unix, Linux и Android 

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

10.8.12. Модель процесса

Традиционная модель процесса, имеющаяся в Linux, — это разветвление (с помощью 
команды fork) для создания нового процесса, за которым следует команда exec для ини-
циализации этого процесса кодом, предназначенным для выполнения, с последующим 
запуском его на выполнение. За управление этим выполнением отвечает оболочка, 
разветвляя и выполняя процессы, необходимые для работы команд оболочки. Когда 
происходит выход из этих команд, Linux удаляет процесс.

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

Запуск процессов

Чтобы запустить новый процесс, диспетчер активностей должен быть связан с про-
цессом zygote. При первом запуске диспетчера активностей он создает выделенный 
сокет с zygote, через который посылает команду, когда нуждается в запуске нового про-
цесса. Команда прежде всего дает описание создаваемой песочницы: UID, под которым 
должен запуститься новый процесс, и любые другие ограничения, связанные с мерами 
безопасности, которые будут применяться. Таким образом, zygote должен запускаться 
с root-правами: при разветвлении он выполняет соответствующую настройку для UID, 
с которым процесс будет запущен, и в конце сбрасывает root-права и изменяет процесс, 
присваивая ему нужный UID.

Вспомним, что в предыдущем рассмотрении Android-приложений говорилось, что 
диспетчер активностей обслуживает динамическую информацию о выполнении ак-
тивностей (см. рис. 10.32), служб (см. рис. 10.37), рассылок (для получателей, как на 
рис. 10.39) и поставщиков контента (см. рис. 10.40). Он использует эту информацию 
для контроля над созданием прикладных процессов и управления ими. Например, 
как показано на рис. 10.32, когда программа запуска приложения осуществляет вызов 
системы с новым намерением на запуск активности, за то, чтобы это новое приложение 
работало, отвечает диспетчер активностей.

Порядок запуска активности в новом процессе показан на рис. 10.45. А вот как выгля-
дят подробности каждого этапа:

1.  Какой-нибудь существующий процесс (например, предназначенный для запуска 

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

2.  Диспетчер активностей просит, чтобы диспетчер пакетов провел разрешение на-

мерения до явного компонента.


background image

10.8. Android   

919

3.  Диспетчер активностей определяет, что прикладной процесс еще не запущен, а за-

тем просит zygote создать новый процесс с соответствующим UID.

4.  Zygote выполняет ветвление, создает новый процесс, являющийся клоном себя 

самого, сбрасывает права и устанавливает его UID песочнице приложения, а за-
тем завершает инициализацию Dalvik в этом процессе для полноценной работы 
среды выполнения Java. Например, после ветвления должны запускаться такие 
потоки, как сборщик мусора.

5.  Новый процесс, представляющий собой клон zygote с полностью установленной 

и работающей Java-средой, осуществляет обратный вызов диспетчера активностей 
с вопросом: «Для чего я нужен?».

6.  Диспетчер активностей возвращает ему полную информацию о запускаемом в нем 

приложении, например о том, где найти его код.

7.  Новый процесс загружает код запускаемого приложения.

8.  Диспетчер активностей отправляет новому процессу любую ожидающую опера-

цию, в данном случае «Запустить активность X».

9.  Новый процесс получает команду на запуск активности, создает экземпляр соот-

ветствующего Java-класса и выполняет его.

Процесс system_server

Прикладной процесс

Экземпляр активности

Код приложения

Android-среда

PackageManagerService

startActivity()

ActivityManagerService

«Кто я такой?»

Загрузка кода 

этого приложения

Создать экземпляр

 этого класса

Процесс zygote

Создать новый 

процесс

Разрешить 
намерение

2

1

3

5

6

8

9

7

4

Рис. 10.45. Этапы запуска нового прикладного процесса

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


background image

920  

 Глава 10. Изучение конкретных примеров: Unix, Linux и Android 

соответствующего компонента. Это может привести к появлению при необходимости 
нового экземпляра активности, запущенного в приложении, как было показано на 
рис. 10.36.

Жизненный цикл процессов

Диспетчер активностей отвечает также за определение того момента, когда процессы 
больше не нужны. Он отслеживает все активности, получатели, службы и поставщики 
контента, запущенные в процессе, в результате чего может определить, насколько важен 
(или неважен) тот или иной процесс.

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

Таблица 10.17. Категории важности процесса

Категория

Описание

oom_adj

SYSTEM

Системные процессы и демоны

−16

PERSISTENT

Постоянно работающие прикладные процессы

−12

FOREGROUND

Процессы, взаимодействующие в данный момент с пользо-
вателем

0

VISIBLE

Процессы, видимые пользователю

1

PERCEPTIBLE

Что-то, о чем знает пользователь

2

SERVICE

Запущенные фоновые службы

3

HOME

Главный (запускающий) процесс

4

CACHED

Неиспользуемый процесс

5

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

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