Background Execution은 모바일 앱이 포그라운드에 없을 때 코드를 실행할 수 있게 해주는 메커니즘입니다. 이 메커니즘이 없으면 앱을 최소화할 때 시스템이 앱을 일시 중단합니다. Apple, 2026에 따르면 iOS는 백그라운드 시간을 30초로 제한하는 반면, Android는 WorkManager 및 Foreground Service를 통해 더 유연한 시나리오를 제공합니다.
핵심 포인트
Background Execution은 사용자가 앱을 최소화하거나 다른 앱으로 전환한 후에도 앱이 코드를 계속 실행할 수 있는 기능입니다. 특별한 메커니즘이 없으면 모바일 OS는 백그라운드로 전환된 후 몇 초 이내에 앱을 Suspended(일시 중단) 상태로 전환하여 활성 앱을 위해 CPU와 메모리를 확보합니다.
모바일 앱은 Foreground(활성), Background(백그라운드), Suspended(일시 중단), Terminated(종료)의 여러 라이프사이클 상태를 거칩니다. Background는 앱이 가시적인 인터페이스 없이 코드를 실행할 수 있는 유일한 상태입니다. iOS와 Android는 이 상태의 기간과 사용 가능한 작업을 다르게 정의합니다.
데이터 동기화, 콘텐츠 다운로드, 푸시 알림 처리, 백그라운드 위치 추적 및 오디오 재생을 위해 백그라운드 실행이 필요합니다. 동기화가 가장 일반적인 시나리오입니다: 앱이 사용자 개입 없이 서버에 데이터를 보내거나 업데이트를 다운로드합니다.
백그라운드 실행의 제한은 에너지 소비, 기기 성능 및 사용자 개인정보 보호의 세 가지 요인에 기인합니다. CPU와 무선 모듈(Wi-Fi, 셀룰러 데이터)이 가장 많은 에너지를 소비합니다 — 모든 백그라운드 프로세스는 배터리 수명을 단축시킵니다.
Google 연구에 따르면 5분마다 백그라운드 작업을 실행하는 앱은 하루에 기기 배터리 수명을 20~30%까지 줄입니다. 한 시간에 한 번의 빈도로 최적화된 백그라운드 작업도 두 개 이상의 앱이 있으면 눈에 띄는 영향을 미칩니다.
각 백그라운드 앱은 RAM을 차지합니다. RAM이 부족하면 시스템이 메모리에서 앱을 언로드하여 사용자가 돌아올 때 다시 시작됩니다. iOS는 Jetsam 알고리즘을 사용합니다 — 메모리 제한을 초과할 때 백그라운드 프로세스를 강제 종료하는 메커니즘입니다. Android도 유사한 원리로 LMK(Low Memory Killer)를 사용합니다.
Android 10 및 iOS 13부터 시스템은 앱이 백그라운드 작업의 목적을 선언하도록 요구합니다. Android는 백그라운드에서 Broadcast Receiver 실행을 제한했습니다. iOS는 프로젝트 Capabilities에서 Background Mode를 지정해야 합니다. 사용자는 설정에서 모든 앱의 백그라운드 실행을 비활성화할 수 있습니다.
| OS | 버전 | 제한 사항 | 영향 |
|---|---|---|---|
| Android | 8.0 | IMPLICIT_BROADCAST 금지 | 67% 백그라운드 Broadcast 손상 |
| Android | 9.0 | Doze 개선 | 네트워크 호출 제한 |
| Android | 12+ | Foreground Service 제한 | 백그라운드 실행 금지 |
| iOS | 7+ | Background App Refresh | 주기적 업데이트 창 |
| iOS | 13+ | BGTaskScheduler | 실행 대신 스케줄링 |
Android는 백그라운드 실행을 위한 여러 메커니즘을 제공하며, 각각 다른 범주의 작업을 해결합니다. WorkManager는 지연 및 정기 작업에 권장되는 API입니다. Foreground Service는 가시적인 알림과 함께 즉시 실행하기 위한 것입니다. JobScheduler는 WorkManager의 하위 수준 대안입니다.
WorkManager는 Android Jetpack의 일부로, 기기 재시작 후에도 완료를 보장하는 백그라운드 작업 실행을 제공합니다. API는 네트워크 상태, 배터리 수준 및 Doze 모드를 고려하여 최적의 실행 시간을 선택합니다. WorkManager는 API 14+와 호환되며 더 이상 사용되지 않는 AlarmManager 및 JobScheduler를 대체합니다.
앱이 사용자에게 표시되는 작업(음악 재생, 위치 기록)을 수행해야 할 때 Foreground Service가 사용됩니다. 서비스는 상태 표시줄에 영구 알림을 표시하고 우선순위가 높습니다 — 작업이 완료될 때까지 시스템이 종료하지 않습니다. Android 13부터 POST_NOTIFICATIONS 권한이 필요합니다.
Android 6.0부터 기기는 유휴 상태일 때 Doze 모드로 전환됩니다. 이 모드에서는 네트워크 작업, 동기화 및 JobScheduler가 연기됩니다. WorkManager는 Doze에 자동으로 적응합니다 — 작업은 유지 관리를 위해 기기가 절전 모드에서 깨어나는 다음 유지 관리 창에서 실행됩니다.
iOS는 백그라운드 실행에 대해 더 엄격한 접근 방식을 사용합니다. Background App Refresh는 정기적인 데이터 업데이트를 위한 기본 메커니즘입니다. BGTaskScheduler는 시스템 상태에 따라 작업을 스케줄링하는 API입니다. 장기 실행 작업을 위해 audio, location, voip, fetch 및 processing의 Background Modes를 사용할 수 있습니다.
Background App Refresh를 사용하면 앱이 데이터를 동기화하기 위해 15~30분마다 깨어날 수 있습니다. 깨어나는 시간은 사용자 행동에 따라 다릅니다 — 시스템은 사용자가 앱을 여는 빈도를 분석합니다. 사용자는 설정 — 일반 — Background App Refresh에서 개별 앱에 대해 이 기능을 비활성화할 수 있습니다.
iOS 13부터 BGTaskScheduler가 더 이상 사용되지 않는 performFetch 및 beginBackgroundTask를 대체했습니다. 앱은 식별자와 최소 간격으로 작업을 등록하고 시스템이 최적의 실행 시간을 결정합니다. 작업은 BGProcessingTask(장기, 10분 이상)와 BGAppRefreshTask(단기, 최대 30초)의 두 가지 유형으로 나뉩니다.
iOS는 백그라운드 작업 실행에 제한된 시간을 할당합니다 — BGAppRefreshTask의 경우 최대 30초, BGProcessingTask의 경우 최대 10분입니다. 제한을 초과하면 시스템이 작업을 강제 종료합니다. 개발자는 중간 결과를 저장하기 위해 만료 처리기(expiration handler)를 호출해야 합니다.
WorkManager를 사용하여 Android에서 백그라운드 실행을 실제로 구현해 보겠습니다. 네트워크 상태를 인식하여 8시간마다 데이터를 동기화하는 예제입니다. WorkManager는 기기 재시작 후에도 작업 실행을 보장합니다.
class SyncWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
return try {
syncDataToServer()
Log.d("Sync", "데이터 동기화됨")
Result.success()
} catch (e: Exception) {
Result.retry()
}
}
}
// 8시간마다 정기 작업 실행
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresCharging(false)
.build()
val syncRequest = PeriodicWorkRequestBuilder<SyncWorker>(
8, TimeUnit.HOURS
).setConstraints(constraints).build()
WorkManager.getInstance(context).enqueue(syncRequest)
사용자에게 표시되는 장기 실행 작업에는 Foreground Service를 사용하세요. 알림에 진행 상황을 표시하는 파일 다운로드 예제입니다. 서비스는 해제할 수 없는 알림과 함께 startForeground()를 호출합니다. 다운로드가 완료되면 stopForeground(STOP_FOREGROUND_REMOVE)를 호출합니다.
class DownloadService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, id: Int): Int {
startForeground(NOTIFICATION_ID, createNotification())
downloadFile()
stopForeground(STOP_FOREGROUND_REMOVE)
stopSelf()
return START_NOT_STICKY
}
private fun createNotification(): Notification {
return NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("파일 다운로드")
.setSmallIcon(android.R.drawable.ic_download)
.build()
}
}
iOS에서 백그라운드 실행은 BGTaskScheduler를 통해 구성됩니다. 콘텐츠 업데이트 작업을 등록하고 실행하는 예제입니다. 앱은 Info.plist에 작업 식별자를 등록하고 작업을 스케줄링해야 할 때 submit을 호출해야 합니다.
import BackgroundTasks
func registerBackgroundTask() {
BGTaskScheduler.shared.register(
forTaskWithIdentifier: "com.app.refresh",
using: nil
) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
}
}
func scheduleAppRefresh() {
let request = BGAppRefreshTaskRequest(
identifier: "com.app.refresh"
)
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
try? BGTaskScheduler.shared.submit(request)
}
func handleAppRefresh(task: BGAppRefreshTask) {
scheduleAppRefresh()
task.expirationHandler = {
// 중간 데이터 저장
cacheCurrentState()
}
fetchLatestData {
task.setTaskCompleted(success: true)
}
}
장기 실행 작업(캐시 정리, 데이터 처리)에는 BGProcessingTask를 사용하세요. 시스템은 실행에 최대 10분을 허용합니다. 기기가 충전 중이고 Wi-Fi에 연결된 경우에만 실행됩니다. Info.plist에 별도의 식별자가 필요하고 register(forTaskWithIdentifier:)를 통한 등록이 필요합니다.
func scheduleProcessing() {
let request = BGProcessingTaskRequest(
identifier: "com.app.cleanup"
)
request.requiresExternalPower = true
request.requiresNetworkConnectivity = true
request.earliestBeginDate = Date(timeIntervalSinceNow: 24 * 60 * 60)
try? BGTaskScheduler.shared.submit(request)
}
Android와 iOS는 백그라운드 실행 철학에서 근본적으로 다릅니다. Android는 더 큰 제어와 함께 유연한 도구를 제공하지만 개발자가 올바른 API를 선택해야 합니다. iOS는 기능을 제한하지만 사용자에게 안정적인 성능과 배터리 수명을 보장합니다.
| 기준 | Android | iOS |
|---|---|---|
| 권장 API | WorkManager | BGTaskScheduler |
| 최대 작업 시간 | 무제한(Foreground Service) | 30초 / 10분(processing) |
| 정기 작업 | 예, PeriodicWorkRequest 통해 | 예, BGAppRefreshTask 통해 |
| 실행 보장 | 예, 재시작 후에도 | 아니요 — 시스템이 결정 |
| 백그라운드 네트워크 액세스 | Doze 모드로 제한 | background config 포함 URLSession 통해 |
| 백그라운드 위치 추적 | Foreground Service + 권한 | Background Mode location + NSLocation |
| 백그라운드 오디오 | 미디어 알림 포함 Foreground Service | Background Mode audio + AVAudioSession |
WorkManager는 앱 상태에 관계없이 완료되어야 하는 작업에 최적입니다: 데이터 동기화, 분석 전송, 큐 처리. API는 기기 종료 후에도 실행을 보장합니다 — 작업은 부팅 후 다시 스케줄링됩니다.
BGTaskScheduler는 시스템이 편리한 시간에 수행할 수 있는 작업에 적합합니다: 새 콘텐츠 다운로드, 위젯 업데이트, 캐시 정리. 긴급 작업에는 적합하지 않습니다 — 기기가 Doze 상태이거나 배터리가 부족하면 시스템이 작업을 지연시킵니다.
자주 묻는 질문
Background Execution은 백그라운드에서 실행되는 모든 코드를 설명하는 일반적인 개념입니다. Background Modes는 앱이 특정 유형의 백그라운드 작업(오디오, 위치, VoIP, fetch)을 수행할 수 있도록 하는 iOS 특정 메커니즘입니다. Android는 Foreground Service 유형을 통해 유사한 접근 방식을 사용합니다.
iOS에서는 BGAppRefreshTask의 표준 제한입니다. 제한에 도달하면 시스템이 작업을 강제 종료합니다. Android에서도 앱이 WorkManager나 Foreground Service를 사용하지 않을 때 유사한 상황이 발생합니다 — 일반 Service는 백그라운드로 전환된 후 시스템에 의해 종료됩니다.
Android에서는 WorkManager를 사용하세요 — 재시작 후에도 실행을 보장합니다. iOS에서는 실행을 보장할 수 없습니다 — 시스템이 작업 실행 시기를 결정합니다. 실행을 보장하는 유일한 방법은 사용자에게 표시되는 표시기와 함께 Background Modes(audio, location)를 사용하는 것입니다.
iOS에서는 UIApplication.shared.backgroundRefreshStatus를 호출합니다 — 상태는 .available, .denied 또는 .restricted입니다. Android에서는 PowerManager.isIgnoringBatteryOptimizations()를 사용하여 배터리 최적화 면제를 확인합니다. WorkManager의 경우 확인이 필요하지 않습니다 — API가 시스템 제한을 자체적으로 처리합니다.
푸시 알림은 백그라운드 코드 없이 작업을 트리거하는 기본 메커니즘입니다. iOS에서는 VoIP용 PushKit과 데이터 업데이트용 Silent Push를 사용할 수 있습니다. Android에서는 High Priority FCM 및 Notification Trampoline을 사용할 수 있습니다. Foreground Service를 통한 WebSocket은 실시간 앱의 대안입니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.