Изучаем AndroidManifest.xml: <service> как подэлемент <application>
В этой статье подробно рассмотрим подэлемент <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>
Comments