Background est un état du cycle de vie d'une application dans lequel elle continue de s'exécuter mais ne s'affiche pas à l'écran. Nous expliquons les bases du travail en arrière-plan sur iOS et Android : limitations, délais d'attente, tâches en arrière-plan via beginBackgroundTask, WorkManager et Service, ainsi que les meilleures pratiques pour un traitement correct de Background.
Points Clés
Background est un état de l'application dans lequel elle continue d'exister dans le système d'exploitation, exécute du code et consomme des ressources, mais ne s'affiche pas sur l'écran de l'appareil. L'utilisateur est sur l'écran d'accueil, dans une autre application ou l'écran de l'appareil est verrouillé. Sur iOS, Background suit Inactive — la chaîne de transition est : Active → Inactive → Background. Sur Android, onStop signale la transition d'une Activity vers Background.
Les deux plateformes imposent des restrictions strictes sur le travail en arrière-plan. iOS offre une fenêtre limitée (généralement 30 secondes) pour exécuter du code après être entré en Background, après quoi l'application passe en Suspended. Android est plus flexible : un Foreground Service avec une notification visible peut fonctionner indéfiniment, mais un Background Service normal est limité à quelques minutes. La tâche principale du développeur est de sauvegarder correctement l'état et de planifier la continuation du travail via les API système de tâches en arrière-plan.
Le système peut terminer une application en arrière-plan à tout moment lorsque la mémoire est insuffisante. Lors de la terminaison, toutes les données non sauvegardées sont perdues. Il est donc crucial de sauvegarder l'état dans applicationDidEnterBackground (iOS) ou onStop (Android). Après la terminaison, le prochain lancement démarre depuis Not Running avec un démarrage à froid et restaure l'état sauvegardé.
Il est important de distinguer Background de Suspended. Background — l'application exécute activement du code. Suspended — l'application est en mémoire mais n'exécute pas de code — elle est gelée. Sur iOS, l'application passe de Background à Suspended après avoir terminé les tâches en arrière-plan. Android n'a pas de Suspended — le processus existe (y compris Background) ou est terminé (Not Running). Cependant, Android peut suspendre l'exécution des threads via LMK (Low Memory Killer).
| Caractéristique | iOS Background | Android Background |
|---|---|---|
| Code exécuté | Oui, jusqu'à 30 secondes | Oui, dépend de l'API |
| UI visible | Non | Non |
| Délai d'attente par défaut | ~30 sec (beginBackgroundTask) | Plusieurs minutes (Service) |
| Travail illimité | Catégories spéciales uniquement (audio, VoIP, navigation) | Foreground Service avec notification |
| Garantie d'exécution | Non — le système peut terminer à tout moment | WorkManager garantit l'exécution |
| Permission requise | Oui — capabilities dans Info.plist | Oui — permission FOREGROUND_SERVICE |
| État suivant | Suspended → Not Running | Not Running (ou redémarrage) |
Sur iOS, Background est géré via la méthode déléguée applicationDidEnterBackground. Dans cette méthode, le développeur doit sauvegarder l'état de l'utilisateur, libérer les ressources et terminer les tâches en arrière-plan. Pour exécuter du code après être entré en Background, on utilise beginBackgroundTask(expirationHandler:) — une API qui demande du temps supplémentaire au système (généralement 30 secondes). Si la tâche n'est pas terminée dans ce délai, expirationHandler est appelé et l'application est forcée de passer en Suspended.
Avec iOS 13, Apple a introduit BGTaskScheduler — une API moderne pour planifier des tâches en arrière-plan. Contrairement à beginBackgroundTask, qui ne donne que du temps pour terminer après être passé en arrière-plan, BGTaskScheduler permet de planifier l'exécution de tâches dans le futur — par exemple, mettre à jour le contenu une fois par heure ou télécharger des analyses la nuit. BGTaskScheduler est l'approche recommandée pour les nouveaux projets, car il est plus efficace en termes de batterie.
import UIKit
import BackgroundTasks
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid
// L'application est passée en arrière-plan — démarrage de la tâche en arrière-plan
func applicationDidEnterBackground(_ application: UIApplication) {
saveAppState()
startBackgroundTask()
}
private func startBackgroundTask() {
backgroundTaskID = UIApplication.shared.beginBackgroundTask { [weak self] in
// Temps écoulé — termine forcément
self?.endBackgroundTask()
}
// Simulation du travail en arrière-plan (sauvegarde des données sur le serveur)
DispatchQueue.global().async { [weak self] in
uploadAnalyticsData()
self?.endBackgroundTask()
}
}
private func endBackgroundTask() {
guard backgroundTaskID != .invalid else { return }
UIApplication.shared.endBackgroundTask(backgroundTaskID)
backgroundTaskID = .invalid
}
// Enregistrement BGTaskScheduler
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
BGTaskScheduler.shared.register(
forTaskWithIdentifier: "com.example.refresh",
using: nil
) { task in
handleAppRefresh(task: task as! BGAppRefreshTask)
}
return true
}
func scheduleAppRefresh() {
let request = BGAppRefreshTaskRequest(identifier: "com.example.refresh")
request.earliestBeginDate = Date(timeIntervalSinceNow: 3600)
try? BGTaskScheduler.shared.submit(request)
}
func handleAppRefresh(task: BGAppRefreshTask) {
scheduleAppRefresh()
task.expirationHandler = { task.setTaskCompleted(success: false) }
fetchLatestData { result in
task.setTaskCompleted(success: result)
}
}
}Le code montre le traitement complet de Background sur iOS. applicationDidEnterBackground lance une tâche en arrière-plan via beginBackgroundTask avec un délai d'attente et expirationHandler. Parallèlement, BGTaskScheduler est enregistré pour des mises à jour périodiques du contenu. beginBackgroundTask est utilisé pour les tâches d'arrêt immédiat, BGTaskScheduler pour la planification à long terme. Les deux API nécessitent une gestion appropriée des identifiants de tâches.
Sur Android, Background est géré via plusieurs API. Le Service traditionnel permet d'exécuter du code en arrière-plan, mais depuis Android 8+ (API 26), le Background Service est limité : le système le termine quelques minutes après que l'application est passée en arrière-plan. Un Foreground Service avec une notification persistante peut fonctionner indéfiniment. WorkManager est la solution recommandée pour les tâches en arrière-plan avec garantie d'exécution même après redémarrage de l'appareil.
Android, contrairement à iOS, prend en charge les processus en arrière-plan de longue durée. Foreground Service est utilisé pour les tâches que l'utilisateur doit voir — lecture de musique, navigation, suivi d'entraînement. JobScheduler et WorkManager sont utilisés pour les tâches qui peuvent être différées : synchronisation de données, téléchargement de logs, mise à jour du cache. La différence clé : Android permet de planifier des tâches avec des conditions — Wi-Fi, charge, inactivité de l'appareil — ce qui économise la batterie et le trafic.
import android.app.Service
import android.content.Intent
import android.os.IBinder
import androidx.work.*
// 1. Foreground Service pour un travail prolongé en arrière-plan
class SyncService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val notification = createNotification()
startForeground(NOTIFICATION_ID, notification)
performBackgroundWork()
return START_STICKY
}
private fun performBackgroundWork() {
Thread {
// Synchronisation des données avec le serveur
syncDataToServer()
stopForeground(STOP_FOREGROUND_REMOVE)
stopSelf()
}.start()
}
override fun onBind(intent: Intent?): IBinder? = null
}
// 2. WorkManager pour les tâches différées en arrière-plan
class DataSyncWorker(
private val context: Context,
private val params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
return try {
// Téléchargement des analyses sur le serveur
uploadAnalytics()
Result.success()
} catch (e: Exception) {
if (runAttemptCount < 3) Result.retry() else Result.failure()
}
}
}
// Planification de la tâche WorkManager
fun scheduleBackgroundSync(context: Context) {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresBatteryNotLow(true)
.build()
val request = OneTimeWorkRequestBuilder<DataSyncWorker>()
.setConstraints(constraints)
.setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 30, TimeUnit.SECONDS)
.build()
WorkManager.getInstance(context).enqueue(request)
}Le code montre deux approches pour le travail en arrière-plan sur Android. SyncService — un Foreground Service avec notification pour un travail immédiat et prolongé en arrière-plan. DataSyncWorker — WorkManager pour les tâches différées avec conditions (Wi-Fi, charge). WorkManager garantit l'exécution même après redémarrage de l'appareil et prend en charge le backoff exponentiel pour les tentatives. Foreground Service nécessite une notification persistante dans la barre d'état.
Les deux plateformes mobiles durcissent constamment les règles du travail en arrière-plan. Sur iOS, chaque nouvelle génération d'OS réduit le temps d'exécution en arrière-plan et ajoute de nouvelles restrictions. Sur Android, Google introduit des modes d'économie d'énergie de plus en plus stricts (Doze, App Standby). Les développeurs doivent se tenir informés des limitations actuelles pour éviter que l'application ne soit terminée prématurément par le système.
Sur iOS, à partir d'iOS 13, le système désactive les tâches en arrière-plan pour les applications qui abusent du temps en arrière-plan. Chaque application reçoit certaines limites basées sur le comportement de l'utilisateur. BGTaskScheduler planifie l'exécution à des moments optimaux — par exemple, lorsque l'appareil est connecté au Wi-Fi et en charge. Les applications qui utilisent correctement BGTaskScheduler obtiennent plus de temps en arrière-plan.
Sur Android, à partir d'Android 9 (API 28), le travail en arrière-plan est restreint par le mode Doze, qui s'active lorsque l'appareil est inactif. Les applications en Doze ne peuvent pas effectuer de tâches en arrière-plan, le réseau est déconnecté, JobScheduler et WorkManager diffèrent les tâches jusqu'à la sortie du Doze. Foreground Service est le seul moyen de contourner Doze, mais l'abus entraîne le blocage de l'application par l'utilisateur et la révocation des autorisations.
| Restriction | iOS | Android |
|---|---|---|
| Délai d'attente tâche arrière-plan | ~30 secondes (beginBackgroundTask) | Plusieurs minutes (JobScheduler) |
| Arrière-plan illimité | Audio, VoIP, navigation, Bluetooth | Foreground Service + notification |
| Économie d'énergie | Low Power Mode — désactive les tâches arrière-plan | Doze, App Standby, Optimisation batterie |
| Planification | BGTaskScheduler (iOS 13+) | WorkManager (Android Jetpack) |
| Après redémarrage | Notification push uniquement | WorkManager conserve les tâches |
| Temps d'exécution max | ~30 minutes (audio) | Illimité (Foreground Service) |
Première règle — minimisez la consommation de ressources en arrière-plan. La plupart des tâches en arrière-plan peuvent être différées au moment où l'appareil est en charge et connecté au Wi-Fi. Utilisez BGTaskScheduler (iOS) et WorkManager (Android) pour planifier des tâches avec conditions. N'exécutez pas de calculs lourds en arrière-plan — cela épuise la batterie et entraîne un ralentissement du CPU.
Deuxième règle — spécifiez toujours un expirationHandler pour beginBackgroundTask. Si l'application ne termine pas la tâche dans le temps imparti, le système la forcera à passer en Suspended ou la terminera. L'expirationHandler est la dernière chance de sauvegarder les données et de terminer le travail correctement. Sur Android, utilisez setForegroundAsync dans WorkManager pour convertir une tâche normale en avant-plan si plus de temps est nécessaire.
Troisième règle — vérifiez les restrictions de travail en arrière-plan avant de lancer. Sur iOS, utilisez UIApplication.shared.backgroundTimeRemaining pour vérifier le temps restant. Sur Android, vérifiez ActivityManager.isBackgroundRestricted() — si true, l'application ne peut pas exécuter de tâches en arrière-plan, et vous devez suggérer à l'utilisateur de supprimer les restrictions dans les paramètres. C'est particulièrement important pour les applications avec des fonctions critiques en arrière-plan — alarmes, calendriers, synchronisation.
Quatrième règle — testez les tâches en arrière-plan sur un appareil réel. Les simulateurs et émulateurs ne reproduisent pas les restrictions réelles du travail en arrière-plan. Sur iOS, utilisez Debug → Simulate Background Fetch dans Xcode. Sur Android, utilisez adb shell am broadcast -a android.intent.action.ACTION_BOOT_COMPLETED pour tester WorkManager après redémarrage. Des tests réels sur un appareil avec une batterie faible révèlent la plupart des problèmes de travail en arrière-plan.
import UIKit
final class BackgroundTaskManager {
static let shared = BackgroundTaskManager()
private var tasks: [String: UIBackgroundTaskIdentifier] = [:]
func startTask(name: String, expiration: @escaping () -> Void) {
let remaining = UIApplication.shared.backgroundTimeRemaining
print("Temps restant en arrière-plan : \(remaining) sec")
let task = UIApplication.shared.beginBackgroundTask { [weak self] in
print("Temps écoulé pour la tâche : \(name)")
expiration()
self?.endTask(name: name)
}
tasks[name] = task
}
func endTask(name: String) {
guard let task = tasks.removeValue(forKey: name),
task != .invalid
else { return }
UIApplication.shared.endBackgroundTask(task)
}
}Le code montre un gestionnaire de tâches en arrière-plan qui suit le temps restant et gère les identifiants. backgroundTimeRemaining retourne le nombre de secondes avant la terminaison forcée — si la valeur est infinie, l'application fonctionne sans restriction (audio, navigation). Le gestionnaire permet de lancer plusieurs tâches en arrière-plan avec différents noms et de terminer chacune correctement. Cette approche évite les fuites de tâches en arrière-plan et garantit que le système ne termine pas l'application en raison de tâches non fermées.
Questions Fréquentes
Oui, pour un nombre limité de catégories : audio (catégorie AVAudioSession .playback), VoIP (PushKit), navigation (CLLocationManager avec allowsBackgroundLocationUpdates), Bluetooth (mode central en arrière-plan), mise à jour en arrière-plan (BGTaskScheduler). Pour toutes les autres — 30 secondes maximum. Dans iOS 16+, Apple a durci les exigences même pour les catégories autorisées.
beginBackgroundTask est une API synchrone pour prolonger la durée de vie de l'application d'environ 30 secondes après être passé en arrière-plan. Il est appelé dans applicationDidEnterBackground. BGTaskScheduler est une API asynchrone pour planifier des tâches dans le futur via des déclencheurs système (temps, emplacement, mise à jour de contenu). BGTaskScheduler est l'approche moderne, recommandée par Apple pour iOS 13+.
Depuis Android 8 (API 26), un Background Service est terminé quelques minutes après que l'application est passée en arrière-plan. Solution : utilisez un Foreground Service avec notification pour les opérations longues ou WorkManager pour les tâches différées. Vérifiez l'Optimisation de la batterie pour votre application dans les paramètres — si elle est optimisée, le système peut différer ou annuler les tâches en arrière-plan.
Appuyez sur Cmd+Shift+H pour aller à l'écran d'accueil. Dans Xcode, utilisez Debug → Simulate Background Fetch. Pour vérifier beginBackgroundTask, ouvrez la console (Shift+Cmd+C) et appelez e UIApplication.shared.backgroundTimeRemaining. Dans Xcode 15+, un scénario Background Execution est disponible dans l'onglet Diagnostics du simulateur.
Process Death est la terminaison d'un processus Android par le système lorsque les ressources sont faibles ou lorsqu'il est inactif en arrière-plan. Contrairement à iOS, Android n'a pas de Suspended — le processus est soit vivant (peut être en arrière-plan), soit mort (Not Running). Process Death est un comportement normal de l'OS, et l'application doit restaurer correctement l'état après cela via SavedStateHandle, onSaveInstanceState ou DataStore.
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