В этой статье подробно рассмотрим подэлемент <service> элемента <application>.

Как известно, файл AndroidManifest предоставляет системе Android исходную, но наиболее важную информацию о приложении, выступая в качестве первой точки, к которой система Android обращается при установке приложения. При объявлении в файле AndroidManifest компонентов, используемых в приложении, система Android получает важнейшую информацию (сколько памяти требуется для работы приложения, какие сервисы реализованы в приложении, какой вид сервиса для циркулярной рассылки используется и т. д.). Эти данные позволяют системе обеспечить бесперебойную работу приложения. 

Подэлемент <service> служит для объявления сервиса фоновой обработки, не имеющего пользовательского интерфейса.

Ключевые атрибуты

  •  android:name

Указывает полное имя пакета объявленного класса Service. В дальнейшем система Android будет использовать это имя для поиска и инициирования нужного класса сервиса.

  • android:label

Указывает удобочитаемое для пользователя имя сервиса.

  • android:description

Указывает удобочитаемое для пользователя описание сервиса.

  • android:icon

Иконка, представляющая сервис, если в этом есть необходимость.

  • android:enabled

Указывает системе Android на возможность/невозможность создавать экземпляры сервиса:

  • "true" (значение по умолчанию)—  сервис разрешен для инстанцирования: система может создавать его экземпляры по мере необходимости;
  • "false"—  сервис считается неинстанцируемым: система не может создавать его экземпляры (отключение).
  • android:exported

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

  • "true"—  сервис доступен из компонентов других приложений и может быть инициирован с помощью полного пути к классу;
  • "false"—  сервис доступен только для компонентов, связанных с данным приложением; компоненты других приложений не могут получить доступ к этой Activity.

Примечание: по умолчанию значение этого атрибута равно “false”, если не указан <intent-filter>. Однако если указан <intent-filter>, значение по умолчанию будет считаться “true”.

  • android:permission

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

Важно понимать, что разрешения для конкретного приложения устанавливаются с помощью элемента <permission> в файле манифеста.

Для примера рассмотрим приложение под названием “MyMusic”, в котором создано пользовательское разрешение “ACCESS_MY_MUSIC_SERVICE” для защиты пользовательского сервиса музыкального плеера. Любое другое приложение, желающее получить доступ к этому сервису в приложении MyMusic, должно обладать этим разрешением.

<manifest>
...
<permission
android:name="com.example.myapp.permission.ACCESS_MY_MUSIC_SERVICE"
android:label="Access music player"
android:description="@string/description_access_music_service"
android:icon="@drawable/ic_access_music_service
android:protectionLevel="normal"/>

<application
...
android:label="MyMusic">
</application>
</manifest>

Однако простое объявление разрешения с помощью элемента <permission> не приводит к автоматическому применению его к любому компоненту. Это все равно что иметь ключ без замка. Чтобы обеспечить такую защиту, нужно связать разрешение с определенным компонентом, перезаписав атрибут “permission” элемента <application> в этом компоненте.

Предположим, что упомянутый выше музыкальный сервис управляется сервисным классом “MyMusicService”. После объявления этого сервиса в элементе <application> прикрепляем объявленное разрешение (ACCESS_MY_MUSIC_SERVICE) с помощью этого атрибута:

<manifest>
...
<permission
android:name="com.example.myapp.permission.ACCESS_MY_MUSIC_SERVICE"
android:label="Access music player"
android:description="@string/description_access_music_service"
android:icon="@drawable/ic_access_music_service"
android:protectionLevel="normal"/>

<application
...
android:label="MyMusic">
</application>

<service
...
android:name=".MyMusicService"
android:permission="com.example.ACCESS_MY_MUSIC_SERVICE"/>
</manifest>

Тем самым гарантируется, что другие приложения смогут получить доступ к этому сервису и его функциям только в том случае, если они объявили это разрешение в своем файле манифеста с помощью элемента <uses-permission>. Доступ предоставляется на основании согласия пользователя.

  • android:process

В Android каждое приложение рассматривается как отдельный пользователь с собственным идентификатором, что обусловлено многопользовательской системой ядра Linux. Следовательно, каждое приложение обрабатывается и запускается с помощью собственной виртуальной машины (VM), что обеспечивает изоляцию кода и данных для повышения безопасности.

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

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

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

В качестве примера рассмотрим банковское приложение с компонентом платежных транзакций. По соображениям безопасности предпочтем обрабатывать платежные транзакции в отдельном процессе, а не в основном процессе VM. Такое разделение обеспечивается атрибутом “process”. Оба процесса работают с одной и той же памятью-кучей, но имеют разные имена, что обеспечивает защиту от потенциальных угроз (в случае угроз в других частях приложения хакерам будет сложнее получить доступ к конфиденциальным данным в этом изолированном компоненте):

  • ":[process_name]"  —  обработка компонента под указанным именем скрытого процесса (символ “:” означает, что этот процесс скрыт, и прямая связь с другими процессами ограничена);
  • "[process_name]"  —  обработка компонента под указанным именем процесса (отсутствие “:” означает, что это “глобальный процесс”, позволяющий взаимодействовать с другими процессами).

Примечание: важно отметить, что подэлементы элемента <application>, такие как <activity> и <service>, обычно переопределяют этот атрибут. При использовании в самом элементе <application> определяется основной процесс для всех компонентов. Если этот атрибут не объявлен, приложение по умолчанию использует один процесс VM, соответствующий имени пакета.

  • android:isolatedProcess

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

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

  • "true"—  сервис будет выполняться в рамках отдельного процесса VM;
  • "false"—  сервис будет выполняться в рамках основного VM-процесса приложения.

Присвоение true указывает системе на создание отдельного VM-процесса для сервиса.

  • android:foregroundServiceType

После версии Android 14 (API 34) в Android появились типы сервисов приоритетной обработки, которые необходимо указывать, если сервис приоритетной обработки работает в фоновом режиме. 

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

  • "camera"  —  указывает на то, что данный сервис приоритетной обработки пытается постоянно обращаться к камере (например, приложение видеочата, допускающее многозадачность);
  • "connectedDevice"  —  указывает на то, что данный сервис приоритетной обработки взаимодействует с внешними устройствами, требующими подключения по Bluetooth, NFC, ИК, USB или сети;
  • "musicPlayback"  —  указывает, что данный сервис приоритетной обработки является сервисом музыкального плеера и система может выполнять соответствующие действия, основанные на типе.

Для просмотра всех сервисов приоритетной обработки можете обратиться к этой официальной документации.

<service
android:name="com.example.service.MyService"
android:label="@string/my_service"
android:description="@string/description_of_my_service"
android:icon="@drawable/ic_my_service"
android:enabled="true"
android:exported="false"
android:permission="com.example.myapp.PERMISSION_USE_SERVICE"
android:process=":my_service_process"
android:isolatedProcess="true"
android:foregroundServiceType="location">

</service>

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи kananbashir: What is AndroidManifest.xml? | <service> sub-element of <application>

Предыдущая статьяОптимизация кода задачи на миллиард строк — ускоряем запуск в 87 раз
Следующая статьяАвтоматизация платежей со Stripe и Golang: руководство разработчика