AOSP Framework & Internals
2 min read

Service

Understand the Service component, designed for long-running background operations without a user interface.

A Service is an application component that can perform long-running operations in the background. It does not provide a user interface.

Even if the user switches to another application, a Service can continue to run (e.g., playing music, downloading a file, or syncing data).

Started vs. Bound Services

Services operate in two fundamentally different modes:

1. Started Services

An app component (like an Activity) calls startService().

  • The service runs indefinitely in the background, even if the component that started it is destroyed.
  • The service must explicitly stop itself by calling stopSelf(), or another component must call stopService().
  • Lifecycle: onCreate() -> onStartCommand().

2. Bound Services

An app component calls bindService().

  • This creates a client-server interface. The component can interact directly with the service, send requests, and get results across process boundaries.
  • The service only runs as long as another application component is bound to it. Once all clients unbind, the OS destroys the service.
  • Lifecycle: onCreate() -> onBind().

Foreground Services

Historically, developers abused Started Services to run silently in the background, draining massive amounts of battery.

To fix this, modern Android requires apps to use Foreground Services for tasks the user is actively aware of (like a music player or an active fitness tracker).

  • A Foreground Service must display an un-dismissible Notification in the status bar.
  • If the app fails to call startForeground() within 5 seconds of starting the service, the OS immediately crashes the app with a SecurityException.
// Example of starting a Foreground Service and displaying the mandatory notification
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE);

Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setContentTitle("Playing Music")
        .setContentText("Song Title")
        .setSmallIcon(R.drawable.ic_music)
        .setContentIntent(pendingIntent)
        .build();

// Tells the OS this service is critical and should not be killed easily
startForeground(1, notification);

ServiceRecord in AMS

Just as Activities are represented by ActivityRecord, Services are tracked in the System Server by a ServiceRecord.

The ActivityManagerService uses the ServiceRecord to track how many clients are bound to the service and how much CPU the service is consuming. If the system experiences extreme RAM pressure, the AMS looks at the ServiceRecord to decide which background services can be safely killed (the OOM Killer).

# View all running services and their internal ServiceRecord states
adb shell dumpsys activity services