Services (Foreground & Background)

📖 Concept

Services are components that run operations without a UI. At the senior level, understanding the OS restrictions, process priority, and WorkManager alternatives is critical.

Types of Services:

  1. Foreground Service — Visible to user (notification required). Higher process priority. Examples: music playback, navigation, file download.
  2. Background Service — No user-visible notification. Heavily restricted since Android 8.0 (Oreo). Killed aggressively by the OS.
  3. Bound Service — Provides a client-server interface. Lives only while clients are bound to it.

Background execution restrictions timeline:

  • Android 6.0 (Doze): Background work paused when device idle
  • Android 8.0: Cannot start background services from background. Must use startForegroundService() + show notification within 5 seconds.
  • Android 12: Foreground service launch restrictions from background. Cannot start FGS from background except in specific cases.
  • Android 14: Must declare foreground service type in manifest (camera, location, mediaPlayback, etc.)

Modern recommendation: Use WorkManager for deferrable background work. Use foreground services only for user-initiated, ongoing tasks.

Process priority (highest to lowest):

  1. Foreground process (Activity in RESUMED state)
  2. Visible process (Activity in STARTED, bound service from visible)
  3. Service process (foreground service running)
  4. Cached process (backgrounded, eligible for killing)

The OS kills processes from lowest to highest priority when memory is low. Understanding this hierarchy is essential for designing reliable background operations.

💻 Code Example

codeTap to expand ⛶
1// Foreground Service with Android 14+ requirements
2class MusicPlayerService : Service() {
3 override fun onCreate() {
4 super.onCreate()
5 createNotificationChannel()
6 }
7
8 override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
9 val notification = buildNotification()
10 // Android 14+ requires foreground service type
11 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
12 startForeground(NOTIFICATION_ID, notification,
13 ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK)
14 } else {
15 startForeground(NOTIFICATION_ID, notification)
16 }
17 startPlayback()
18 return START_NOT_STICKY // Don't restart if killed
19 }
20
21 override fun onBind(intent: Intent?): IBinder? = null
22
23 override fun onDestroy() {
24 stopPlayback()
25 super.onDestroy()
26 }
27}
28
29// Starting from Android 8.0+
30// From foreground (Activity visible):
31ContextCompat.startForegroundService(context,
32 Intent(context, MusicPlayerService::class.java))
33
34// WorkManager for deferrable background work (preferred)
35class SyncWorker(context: Context, params: WorkerParameters)
36 : CoroutineWorker(context, params) {
37
38 override suspend fun doWork(): Result {
39 return try {
40 val repository = EntryPoints.get(applicationContext,
41 SyncEntryPoint::class.java).repository()
42 repository.sync()
43 Result.success()
44 } catch (e: Exception) {
45 if (runAttemptCount < 3) Result.retry() else Result.failure()
46 }
47 }
48}
49
50// Enqueue periodic sync
51val syncRequest = PeriodicWorkRequestBuilder<SyncWorker>(
52 15, TimeUnit.MINUTES
53).setConstraints(
54 Constraints.Builder()
55 .setRequiredNetworkType(NetworkType.CONNECTED)
56 .setRequiresBatteryNotLow(true)
57 .build()
58).setBackoffCriteria(
59 BackoffPolicy.EXPONENTIAL, 1, TimeUnit.MINUTES
60).build()
61
62WorkManager.getInstance(context)
63 .enqueueUniquePeriodicWork("sync", ExistingPeriodicWorkPolicy.KEEP, syncRequest)

🏋️ Practice Exercise

Practice:

  1. Implement a foreground service for file download with progress notification
  2. Explain the difference between START_STICKY, START_NOT_STICKY, and START_REDELIVER_INTENT
  3. Why can't you start a background service from Android 8.0+? What alternatives exist?
  4. Implement a WorkManager chain: download file → process → upload result
  5. Explain how bound services work and when you'd use them over other IPC mechanisms

⚠️ Common Mistakes

  • Not showing a notification within 5 seconds of startForegroundService() — causes ForegroundServiceDidNotStartInTimeException crash

  • Using background services for work that should use WorkManager — services are killed aggressively, WorkManager guarantees execution

  • Not declaring foreground service types in AndroidManifest on Android 14+ — runtime crash

  • Leaking bound service connections — always unbind in the appropriate lifecycle callback

💼 Interview Questions

🎤 Mock Interview

Mock interview is powered by AI for Services (Foreground & Background). Login to unlock this feature.