Background Service est un composant Android conçu pour effectuer des opérations longues en arrière-plan sans interface utilisateur. Contrairement à Activity, Service continue de fonctionner même après que l’application est minimisée ou que l’utilisateur est passé à une autre application. Selon Android Developers, 2026, il existe trois types de services : Started Service, Bound Service et Foreground Service, chacun avec son propre cycle de vie et domaine d’application.
Points clés
Background Service (ou simplement Service) est l’un des quatre composants fondamentaux d’une application Android, avec Activity, BroadcastReceiver et ContentProvider. Contrairement à Activity, Service n’a pas d’interface visuelle et est conçu pour effectuer des opérations qui doivent se poursuivre indépendamment du fait que l’application soit au premier plan ou non.
Service s’exécute sur le thread principal de l’application, donc toute opération bloquante à l’intérieur nécessite la création d’un thread séparé. Si cela n’est pas fait, le système génère une ANR (Application Not Responding). Pour les opérations simples en arrière-plan, Android fournit IntentService, qui crée automatiquement un thread de travail. Dans les projets modernes, il est recommandé d’utiliser les coroutines Kotlin avec CoroutineScope à l’intérieur de Service pour un traitement asynchrone sans bloquer le thread principal.
Le but principal de Service est la lecture de musique, le téléchargement de fichiers, la gestion des requêtes réseau, la synchronisation de données et d’autres tâches qui doivent continuer après le départ de l’utilisateur de l’application. Cependant, depuis Android 8, les développeurs doivent choisir consciemment entre les types de services, en tenant compte des restrictions du travail en arrière-plan.
Service a son propre cycle de vie, qui diffère de celui d’Activity. Il comprend quatre méthodes clés : onCreate, onStartCommand, onBind et onDestroy. Comprendre ce cycle est essentiel pour implémenter correctement les tâches en arrière-plan sans fuites mémoire.
La méthode onCreate est appelée à la création du service, une fois pendant sa durée de vie. Les ressources telles que les minuteurs, les connexions de base de données et les sockets sont initialisées ici. La méthode onStartCommand est appelée chaque fois que startService est invoqué, permettant d’envoyer des commandes à un service déjà en cours d’exécution. La valeur de retour détermine le comportement du système au redémarrage.
class DownloadService : Service() {
override fun onCreate() {
super.onCreate()
initializeDownloader()
}
override fun onStartCommand(
intent: Intent?,
flags: Int,
startId: Int
): Int {
downloadFile(intent?.getStringExtra("url"))
return START_STICKY
}
override fun onBind(intent: Intent): IBinder? = null
}
onBind est appelé lors de la liaison d’un service via bindService et retourne un objet IBinder pour l’interaction avec le client. Cette méthode est utilisée uniquement pour Bound Service. onDestroy est le dernier appel avant la destruction du service. Toutes les ressources sont libérées, les threads arrêtés et les tâches annulées ici.
Android propose trois types de Service, chacun conçu pour son propre scénario. Choisir le mauvais type peut entraîner un comportement instable de l’application ou une consommation de batterie.
Started Service est démarré en appelant startService et fonctionne jusqu’à ce qu’il appelle stopSelf ou stopService. Il convient aux tâches qui doivent être exécutées immédiatement : envoi d’analyses, traitement d’une image, téléchargement d’un seul fichier. Après avoir terminé son travail, le service s’arrête de lui-même.
Bound Service fournit une interface client-serveur, permettant à une Activity, un Fragment ou un autre composant d’interagir avec le service. Le service vit tant qu’il y a au moins un client lié. Lorsque tous les clients se délient, le service est détruit. Bound Service est utile pour les tâches nécessitant une communication bidirectionnelle : lecteur de musique, navigation.
Foreground Service est un Started Service avec une notification persistante dans la barre d’état. Le système considère un tel service comme actif et ne le tue pas même en cas de faible mémoire. Foreground Service est obligatoire pour la lecture de musique, l’enregistrement audio, le suivi de localisation et d’autres tâches importantes pour l’utilisateur.
| Paramètre | Started | Bound | Foreground |
|---|---|---|---|
| Démarrage | startService | bindService | startForeground |
| Durée de vie | jusqu’à stopSelf | tant que des clients existent | jusqu’à stopForeground |
| Notification | non | non | obligatoire |
| Tuable | oui | oui | non |
| Exemple | téléchargement | lecteur | musique |
Créer un service commence par déclarer une classe qui hérite de Service et l’enregistrer dans AndroidManifest.xml. Sans enregistrement dans le manifeste, le système ne pourra pas démarrer le service, et tout appel à startService entraînera une exception.
// Enregistrement dans AndroidManifest.xml
@SuppressLint("ForegroundServiceType")
class SyncService : Service() {
override fun onStartCommand(
intent: Intent?,
flags: Int,
startId: Int
): Int {
startForeground(
NOTIFICATION_ID,
createNotification()
)
performSync(intent)
return START_NOT_STICKY
}
}
Pour démarrer un service à partir d’une Activity ou d’un Fragment, un Intent avec une référence explicite à la classe du service est utilisé. À partir d’Android 8, Foreground Service nécessite l’autorisation FOREGROUND_SERVICE dans le manifeste.
// Démarrer un Started Service
val intent = Intent(this, SyncService::class.java)
intent.putExtra("action", "sync")
startService(intent)
// Démarrer un Foreground Service (Android 8+)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent)
} else {
startService(intent)
}
À partir d’Android 8 (API 26), Google a introduit des restrictions strictes sur les services en arrière-plan. Le démarrage d’un service en arrière-plan (lorsque l’application n’est pas au premier plan) n’est autorisé que dans des cas exceptionnels : lors de la réception d’une notification push, après le démarrage de l’appareil ou via JobScheduler.
Pour les tâches longues qui ne nécessitent pas d’exécution immédiate, il est recommandé d’utiliser WorkManager ou JobScheduler. Si une application a vraiment besoin d’un service en cours d’exécution, la seule façon est un Foreground Service avec une notification visible par l’utilisateur. Démarrer un service sans notification en arrière-plan sera ignoré par le système.
JobIntentService est une classe spécialisée apparue dans la bibliothèque de support pour fonctionner sous Android 5+. Elle combine le comportement d’IntentService (thread de travail automatique, traitement séquentiel) avec la planification via JobScheduler. Sous Android 8+, JobIntentService utilise JobScheduler en interne, et sur les versions plus anciennes, un Service normal. Cela permet un traitement uniforme des tâches en arrière-plan sans vérifications supplémentaires de la version Android.
class UploadJobService : JobIntentService() {
companion object {
private const val JOB_ID = 1000
fun enqueueWork(context: Context, work: Intent) {
enqueueWork(
context,
UploadJobService::class.java,
JOB_ID,
work
)
}
}
override fun onHandleWork(intent: Intent) {
val fileUri = intent.getStringExtra("file_uri")
// S’exécute dans un thread d’arrière-plan
uploadFile(fileUri)
}
}
L’un des problèmes courants lors du travail avec Background Service est les fuites mémoire. Étant donné qu’un Service peut vivre plus longtemps qu’une Activity, les références à Activity à l’intérieur de Service (via listener, callback ou broadcast) empêchent le ramasse-miettes des composants UI. Il est recommandé d’utiliser WeakReference, ViewModel ou LiveData pour la communication Service-UI. Dans onDestroy, n’oubliez pas d’annuler tous les abonnements, d’arrêter les threads et de fermer les curseurs.
Le choix entre Background Service et WorkManager dépend du scénario. Service convient aux tâches qui doivent être exécutées immédiatement et en continu : lecture de musique, enregistrement audio, suivi GPS. WorkManager est meilleur pour les tâches différées et garanties : synchronisation, envoi d’analyses, téléchargement de logs. WorkManager survit aux redémarrages de l’appareil, contrairement à Service. Service peut être en premier plan avec notification, tandis que WorkManager fonctionne silencieusement en arrière-plan. En pratique, les développeurs combinent les deux approches : Foreground Service pour les tâches critiques pour l’utilisateur et WorkManager pour la maintenance en arrière-plan.
Android 12 a introduit le drapeau android:foregroundServiceType, qui nécessite de spécifier le type de service : dataSync, camera, connectedDevice, location, mediaPlayback et autres. Une spécification incorrecte du type entraîne une exception au démarrage. Cette pratique rend Background Service plus transparent pour l’utilisateur et le système.
L’enregistrement correct de Service dans le manifeste inclut l’attribut exported (accessibilité aux applications externes), le foregroundServiceType (type de service en arrière-plan sous Android 12+) et l’autorisation. Pour Bound Service, vous devez également déclarer android:permission="android.permission.BIND_JOB_SERVICE" pour JobIntentService. Sans enregistrement dans le manifeste, tout appel à startService ou bindService lèvera une exception, donc la vérification du manifeste est la première étape lors du diagnostic des problèmes liés à Service.
Questions fréquentes
Service s’exécute sur le thread principal (UI Thread) de l’application. Toute opération bloquante dans onStartCommand ou onHandleIntent doit être déplacée vers un thread séparé ou une coroutine, sinon le système génère une ANR après 5 secondes.
IntentService est une sous-classe de Service qui crée automatiquement un thread de travail et traite les commandes séquentiellement. Après avoir terminé la dernière tâche, IntentService s’arrête tout seul. À partir d’Android 8, IntentService est considéré comme obsolète au profit de JobIntentService ou WorkManager.
Démarrer un Started Service depuis l’arrière-plan sur Android 12 est interdit. L’exception est un Foreground Service avec foregroundServiceType déclaré dans le manifeste et une notification valide. Un démarrage court après réception d’un message FCM haute priorité est également autorisé.
Il existe trois méthodes : BroadcastReceiver avec diffusion locale, le mécanisme Messenger via Handler, et LiveData/Flow dans l’architecture MVVM avec un ViewModel partagé. Pour Bound Service, IBinder est utilisé avec des appels de méthodes directs.
Si un Service a été démarré avec le drapeau START_STICKY, le système le redémarre après que le processus a été tué par manque de mémoire. Le drapeau START_NOT_STICKY signifie que le système ne redémarrera pas le service. START_REDELIVER_INTENT est similaire à START_STICKY mais délivre le dernier Intent.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi