Skip to content

MASTG-KNOW-0133: Android Services

A service is an app component that performs long-running operations in the background without a user interface, such as processing data, performing network transactions, or interacting with content providers. A service extends the Service class. Unless configured otherwise, a service runs in the main thread of its hosting process and does not create its own thread.

Services are an inter-process communication (IPC) entry point: other apps and the system can start or bind to a service through an Intent, subject to manifest access controls such as android:exported and android:permission. This makes service visibility directly relevant to the app's attack surface. See Inter-Process Communication (IPC) Mechanisms for the IPC model and the role of Binder.

Declaration

Each service must be declared in the AndroidManifest.xml file with a <service> element nested inside <application>:

<service android:name=".MyService" />

The android:process attribute can place the service in a separate process (for example, android:process=":remote"), which is common for services that expose a remote interface to other apps.

Types of Services

Android distinguishes services by how they are used:

For background work that doesn't need to run immediately, modern Android favors WorkManager and JobScheduler over long-running started services.

Communicating with a Bound Service

Apps interact with a bound service through one of these mechanisms:

  • A Messenger, which serializes requests into Message objects delivered to a Handler. This is the simplest cross-process interface.
  • The Android Interface Definition Language (AIDL), which generates the marshalling code for a remote interface and allows concurrent calls across processes.
  • A local Binder subclass, when the service is only used within the same process.

The inputs a service expects (for example, the what field and arguments of a Message, or the methods of an AIDL interface) are defined in the service implementation. See Inter-Process Communication (IPC) Mechanisms for how Binder transactions carry these calls between processes.

Access Control

Whether other apps can start or bind to a service is governed by manifest attributes:

  • android:exported: when true, components of other apps can start or bind to the service unless another control, such as android:permission, blocks the caller. When false, access is limited to the same app, apps with the same user ID, or privileged system components. Declaring an <intent-filter> historically caused android:exported to default to true; since Android 12 (API level 31) the attribute must be set explicitly when an intent filter is present.
  • android:permission: requires the caller to hold a specific permission to start or bind to the service. If the caller is not granted the permission, the intent is not delivered to the service. Combined with a custom permission and an appropriate android:protectionLevel (for example, signature), this restricts which apps can interact with the component. See App Permissions for permission protection levels, component permission enforcement, and custom permissions, and see Permission-based access control to exported components.
  • Inside the service, Context.checkCallingPermission and related methods can verify at runtime whether the caller holds a required permission before processing a Binder transaction. See Binder and Messenger interfaces.

For an overview of how to restrict access to exported components, see Restrict Access to Android App Components.