ANDROID: Android Service

Android Services are components that perform long-running background operations without a user interface. Understanding the three types of services — Foreground, Background, and Bound — and their lifecycle methods is essential for building robust Android apps that work reliably behind the scenes.

Most Android applications need to do work that does not happen on screen. Music must keep playing while the user browses their contacts. A file must finish downloading even if the user switches to another app. Location updates must continue while navigation is active. These are all problems that Services solve.

A Service is an Android application component designed specifically for background work without a UI. It runs independently of any Activity, can persist across user navigation, and can be initiated by or communicate with other parts of the application.


What is an Android Service?

An Android Service is a component that:

  • Runs in the background — it continues executing even when the user switches to another application
  • Has no user interface — unlike Activities, Services have no visual representation
  • Performs long-running tasks — network requests, audio playback, data synchronization, file processing
  • Communicates with other components — it can send notifications, broadcast intents, or expose a programmatic interface to Activities

md
+-------------------------------------------+
|              Android App Process           |
|                                           |
|   +----------+       +----------+         |
|   | Activity |       | Service  |         |
|   | (UI)     |<----->| (No UI)  |         |
|   +----------+       +----------+         |
|                           |               |
|                   Background work         |
|                   (network, audio, sync)  |
+-------------------------------------------+


Types of Android Services

Android defines three distinct types of services, each designed for a different use case and with different behaviors under system resource pressure.

1. Foreground Service

A Foreground Service is a service that performs work the user is actively aware of. It is considered critical by the Android system and is therefore given high priority — it is far less likely to be killed when the system is under memory pressure.

The defining requirement of a Foreground Service is that it must display a persistent notification as long as it is running. This is not optional — it is what signals to the user (and to the system) that something important is happening in the background.

Use cases:

  • Music or podcast players
  • Active navigation / turn-by-turn directions
  • Fitness tracking during a workout
  • Ongoing file uploads or downloads that the user initiated

java
// Start a foreground service with a persistent notification
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setContentTitle("Foreground Service")
        .setContentText("Service is running in the foreground")
        .setSmallIcon(R.drawable.ic_service)
        .build();

startForeground(1, notification);

The startForeground() call associates the notification with the service. As long as the service runs, the notification stays. When the service stops, the notification is automatically removed.


2. Background Service

A Background Service runs without any user-visible indication. It performs work that the user does not need to be aware of while it is happening.

Important: Starting with Android 8.0 (API level 26), the Android system introduced significant restrictions on background services to improve battery life and system performance. Apps that target API 26 or higher cannot start background services when the app is not in the foreground. The system throttles and eventually kills background services to reclaim resources.

Use cases:

  • Periodic data synchronization with a server
  • Pre-fetching content while the app is in the foreground
  • Processing data that does not require user awareness

Because of the API 26 restrictions, JobScheduler, WorkManager, or Foreground Services are often preferred over raw background services for reliable background work in modern Android.


3. Bound Service

A Bound Service is a service that exposes a programmatic interface for other components to interact with. An Activity (or another service) can bind to it, call methods on it, and receive results — essentially using the service as a remote object.

A Bound Service runs only as long as at least one component is bound to it. When all clients unbind, the system destroys the service automatically (unless it was also started with startService()).

Use cases:

  • Exposing sensor data or hardware state to multiple UI components
  • Providing a music playback controller that Activities can query and control
  • Cross-process communication via AIDL

java
// Binding to a service from an Activity
ServiceConnection connection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder service) {
        MyService.LocalBinder binder = (MyService.LocalBinder) service;
        myService = binder.getService();
        mBound = true;
    }

    public void onServiceDisconnected(ComponentName arg0) {
        mBound = false;
    }
};

Intent intent = new Intent(this, MyService.class);
bindService(intent, connection, Context.BIND_AUTO_CREATE);


Service Lifecycle

Services have two distinct lifecycle paths depending on how they are used.

md
Started Service Lifecycle:

startService() --> onCreate() --> onStartCommand() --> [Running]
                                                            |
                                             stopSelf() or stopService()
                                                            |
                                                       onDestroy()

Bound Service Lifecycle:

bindService() --> onCreate() --> onBind() --> [Bound]
                                                  |
                                          all clients unbind
                                                  |
                                             onUnbind() --> onDestroy()

Started Service

A service is started when a component calls startService(). The service runs indefinitely until:

  • It calls stopSelf() internally when its work is complete
  • Another component calls stopService() from outside

java
Intent serviceIntent = new Intent(this, MyService.class);
startService(serviceIntent);

Started services are well-suited for long-running background tasks that do not need to return results to the caller — like playing audio or downloading a file.

Bound Service

A service is bound when a component calls bindService(). The service lives only as long as something is bound to it.

java
bindService(new Intent(this, MyService.class), serviceConnection, Context.BIND_AUTO_CREATE);


Service Lifecycle Methods

Every service class can override these key methods:

`onCreate()`

Called once when the service is first created, before either onStartCommand() or onBind(). This is where you initialize resources — network connections, file handles, threads, handlers.

java
@Override
public void onCreate() {
    super.onCreate();
    // Initialize resources needed by the service
}

`onStartCommand()`

Called every time a client calls startService(). This is where the service actually performs its work. It receives the Intent that was passed to startService(), which can carry data about what work to do.

onStartCommand() must return one of three constants that tell the system what to do if the service is killed:

Return ValueBehavior
START_STICKYRestart the service after it is killed, but do not re-deliver the original Intent
START_NOT_STICKYDo not restart the service after it is killed
START_REDELIVER_INTENTRestart the service and re-deliver the last Intent that was used to start it

java
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // Perform background work here
    return START_STICKY;
}

`onBind()`

Called when a component wants to bind to the service. Returns an IBinder object that defines the communication interface. For services that are not intended to be bound, return null.

java
@Override
public IBinder onBind(Intent intent) {
    return binder; // Return null if not a bound service
}

`onUnbind()`

Called when all clients have unbound from the service. Override this to clean up resources that were created for the bound clients.

`onDestroy()`

Called when the service is being destroyed — either because it stopped itself, was stopped by another component, or the system is reclaiming resources. This is your last opportunity to clean up: stop background threads, release network connections, unregister listeners.

java
@Override
public void onDestroy() {
    super.onDestroy();
    // Clean up all resources
}


A Complete Service Example

java
public class MyService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        // Initialize resources needed by the service
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // Perform your background task here
        // Return START_STICKY to restart if killed
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // Return null for a started-only service
        // Return a Binder object for a bound service
        return null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // Clean up resources here
    }
}


Common Service Use Cases

Use CaseService TypeNotes
Music / podcast playbackForegroundRequires persistent notification
File downloadForegroundUser should see download progress
Background data syncWorkManagerPreferred over raw Background Service on API 26+
Location trackingForegroundRequired for continuous location on modern Android
Exposing hardware stateBoundService lives while clients are connected
Cross-process APIBound + AIDLUse when clients are in different processes

Summary

  • A Service performs background work without a UI
  • Foreground Services are high-priority, require a notification, and are used for user-visible work
  • Background Services run silently but are heavily restricted on Android 8.0+
  • Bound Services expose an interface for direct client interaction and die when all clients unbind
  • The lifecycle methods — onCreate(), onStartCommand(), onBind(), onDestroy() — control how the service initializes, works, and cleans up

Services are the backbone of background processing in Android. Understanding which type to use and when to use it is a critical skill for building reliable, battery-efficient applications.