Background: 기초, iOS 및 Android에서 앱의 백그라운드 작업

저자: IT Sectr 게시일: 2026-03-03 읽는 시간: 10 분

Background는 앱이 계속 실행되지만 화면에 표시되지 않는 라이프사이클 상태입니다. iOS 및 Android에서 백그라운드 작업의 기초를 설명합니다: 제한 사항, 시간 초과, beginBackgroundTask, WorkManager 및 Service를 통한 백그라운드 작업, 그리고 Background의 올바른 처리를 위한 모범 사례.

핵심 사항

  • Background — 앱이 사용자에게 보이지 않지만 제한된 시간 동안 코드를 실행할 수 있음
  • iOS 백그라운드 작업 — beginBackgroundTask(expirationHandler:)가 작업 완료에 최대 30초 제공
  • Android Service — 긴 백그라운드 작업을 위한 알림 포함 Foreground Service
  • WorkManager — 실행 보장과 함께 Android 백그라운드 작업에 권장되는 API
  • 제한 사항 — 두 플랫폼 모두 배터리 절약을 위해 백그라운드 작업 규칙 강화

Background — 백그라운드 상태의 기초

Background는 앱이 운영 체제에 계속 존재하고, 코드를 실행하며 리소스를 소비하지만 기기 화면에 표시되지 않는 상태입니다. 사용자가 홈 화면, 다른 앱에 있거나 기기 화면이 잠겨 있습니다. iOS에서 Background는 Inactive 다음에 옵니다 — 전환 체인: Active → Inactive → Background. Android에서 onStop은 Activity의 Background 전환을 알립니다.

두 플랫폼 모두 백그라운드 작업에 엄격한 제한을 가합니다. iOS는 Background 진입 후 코드 실행을 위해 제한된 시간(보통 30초)을 제공하며, 이후 앱은 Suspended로 전환됩니다. Android는 더 유연합니다: 표시 알림이 있는 Foreground Service는 무제한으로 실행될 수 있지만, 일반 Background Service는 몇 분으로 제한됩니다. 개발자의 주요 작업은 상태를 올바르게 저장하고 시스템 백그라운드 작업 API를 통해 작업을 계속할 수 있도록 예약하는 것입니다.

시스템은 메모리가 부족할 때 언제든지 백그라운드 앱을 종료할 수 있습니다. 종료 시 저장되지 않은 모든 데이터가 손실됩니다. 따라서 applicationDidEnterBackground(iOS) 또는 onStop(Android)에서 상태를 저장하는 것이 매우 중요합니다. 종료 후 다음 실행은 Not Running에서 콜드 스타트로 시작하여 저장된 상태를 복원합니다.

Background vs Suspended

Background와 Suspended를 구분하는 것이 중요합니다. Background — 앱이 활발히 코드를 실행 중입니다. Suspended — 앱이 메모리에 있지만 코드를 실행하지 않습니다 — 중단(frozen) 상태입니다. iOS에서 앱은 백그라운드 작업 완료 후 Background에서 Suspended로 전환됩니다. Android에는 Suspended가 없습니다 — 프로세스가 존재하거나(Background 포함) 종료(Not Running)됩니다. 그러나 Android는 LMK(Low Memory Killer)를 통해 스레드 실행을 일시 중단할 수 있습니다.

특성iOS BackgroundAndroid Background
코드 실행예, 최대 30초예, API에 따라 다름
UI 표시아니오아니오
기본 시간 초과~30초(beginBackgroundTask)몇 분(Service)
무제한 작업특별 카테고리만(오디오, VoIP, 내비게이션)알림 포함 Foreground Service
실행 보장없음 — 시스템이 언제든지 종료 가능WorkManager가 실행 보장
권한 필요예 — Info.plist의 capabilities예 — FOREGROUND_SERVICE 권한
다음 상태Suspended → Not RunningNot Running(또는 재시작)

iOS의 Background: Swift, beginBackgroundTask 및 BGTaskScheduler

iOS에서 Background는 델리게이트 메서드 applicationDidEnterBackground를 통해 처리됩니다. 이 메서드에서 개발자는 사용자 상태를 저장하고, 리소스를 해제하며, 백그라운드 작업을 완료해야 합니다. Background 진입 후 코드를 실행하려면 beginBackgroundTask(expirationHandler:)를 사용합니다 — 시스템에 추가 시간(보통 30초)을 요청하는 API입니다. 이 시간 내에 작업이 완료되지 않으면 expirationHandler가 호출되고 앱이 강제로 Suspended로 전환됩니다.

iOS 13에서 Apple은 BGTaskScheduler를 도입했습니다 — 백그라운드 작업을 예약하기 위한 최신 API입니다. 백그라운드 전환 후 종료 시간만 제공하는 beginBackgroundTask와 달리, BGTaskScheduler는 미래의 작업 실행을 예약할 수 있습니다 — 예를 들어, 한 시간에 한 번 콘텐츠 업데이트 또는 야간 분석 업로드 등입니다. BGTaskScheduler는 새 프로젝트에 권장되는 접근 방식이며, 배터리 효율성이 더 뛰어납니다.

swift
import UIKit
import BackgroundTasks

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid

    // 앱이 백그라운드로 전환됨 — 백그라운드 작업 시작
    func applicationDidEnterBackground(_ application: UIApplication) {
        saveAppState()
        startBackgroundTask()
    }

    private func startBackgroundTask() {
        backgroundTaskID = UIApplication.shared.beginBackgroundTask { [weak self] in
            // 시간 초과 — 강제 종료
            self?.endBackgroundTask()
        }

        // 백그라운드 작업 시뮬레이션(서버에 데이터 저장)
        DispatchQueue.global().async { [weak self] in
            uploadAnalyticsData()
            self?.endBackgroundTask()
        }
    }

    private func endBackgroundTask() {
        guard backgroundTaskID != .invalid else { return }
        UIApplication.shared.endBackgroundTask(backgroundTaskID)
        backgroundTaskID = .invalid
    }

    // 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)
        }
    }
}

코드는 iOS의 완전한 Background 처리를 보여줍니다. applicationDidEnterBackground가 시간 초과 및 expirationHandler와 함께 beginBackgroundTask를 통해 백그라운드 작업을 시작합니다. 동시에 BGTaskScheduler가 정기적인 콘텐츠 업데이트를 위해 등록됩니다. beginBackgroundTask는 즉시 종료 작업에 사용되고, BGTaskScheduler는 장기 계획에 사용됩니다. 두 API 모두 작업 식별자의 올바른 관리가 필요합니다.

Android의 Background: Kotlin, Service, WorkManager

Android에서 Background는 여러 API를 통해 관리됩니다. 전통적인 Service는 백그라운드에서 코드 실행을 허용하지만, Android 8+(API 26)부터 Background Service는 제한됩니다: 앱이 백그라운드로 전환된 후 몇 분 내에 시스템이 종료합니다. 지속적인 알림이 있는 Foreground Service는 무제한으로 실행될 수 있습니다. WorkManager는 기기 재시작 후에도 실행 보장과 함께 백그라운드 작업에 권장되는 솔루션입니다.

Android는 iOS와 달리 장기 실행 백그라운드 프로세스를 지원합니다. Foreground Service는 사용자가 볼 수 있어야 하는 작업(음악 재생, 내비게이션, 운동 추적)에 사용됩니다. JobScheduler와 WorkManager는 지연 가능한 작업(데이터 동기화, 로그 업로드, 캐시 업데이트)에 사용됩니다. 주요 차이점: Android는 조건(Wi-Fi, 충전 중, 기기 유휴 상태)으로 작업을 예약할 수 있어 배터리와 트래픽을 절약합니다.

kotlin
import android.app.Service
import android.content.Intent
import android.os.IBinder
import androidx.work.*

// 1. 장기 백그라운드 작업을 위한 Foreground Service
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 {
            // 서버와 데이터 동기화
            syncDataToServer()
            stopForeground(STOP_FOREGROUND_REMOVE)
            stopSelf()
        }.start()
    }

    override fun onBind(intent: Intent?): IBinder? = null
}

// 2. 지연 백그라운드 작업을 위한 WorkManager
class DataSyncWorker(
    private val context: Context,
    private val params: WorkerParameters
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        return try {
            // 서버에 분석 업로드
            uploadAnalytics()
            Result.success()
        } catch (e: Exception) {
            if (runAttemptCount < 3) Result.retry() else Result.failure()
        }
    }
}

// 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)
}

코드는 Android의 백그라운드 작업에 대한 두 가지 접근 방식을 보여줍니다. SyncService — 즉각적이고 장기적인 백그라운드 작업을 위한 알림 포함 Foreground Service. DataSyncWorker — 조건(Wi-Fi, 충전)이 있는 지연 작업을 위한 WorkManager. WorkManager는 기기 재시작 후에도 실행을 보장하고 재시도를 위한 지수 백오프를 지원합니다. Foreground Service는 상태 표시줄에 지속적인 알림이 필요합니다.

iOS 및 Android의 백그라운드 작업 제한 사항

두 모바일 플랫폼 모두 지속적으로 백그라운드 작업 규칙을 강화하고 있습니다. iOS에서는 OS의 새 세대마다 백그라운드 실행 시간이 줄어들고 새로운 제한이 추가됩니다. Android에서는 Google이 점점 더 엄격한 절전 모드(Doze, App Standby)를 도입하고 있습니다. 개발자는 현재 제한 사항을 파악하고 있어야 앱이 시스템에 의해 조기에 종료되지 않습니다.

iOS에서는 iOS 13부터 시스템이 백그라운드 시간을 남용하는 앱의 백그라운드 작업을 비활성화합니다. 각 앱은 사용자 행동에 따라 특정 제한을 받습니다. BGTaskScheduler는 최적의 시간(예: 기기가 Wi-Fi에 연결되고 충전 중일 때)에 실행을 예약합니다. BGTaskScheduler를 올바르게 사용하는 앱은 더 많은 백그라운드 시간을 얻습니다.

Android에서는 Android 9(API 28)부터 백그라운드 작업이 Doze 모드에 의해 제한되며, 기기가 유휴 상태일 때 활성화됩니다. Doze 상태의 앱은 백그라운드 작업을 수행할 수 없고, 네트워크가 차단되며, JobScheduler와 WorkManager는 Doze 종료까지 작업을 연기합니다. Foreground Service가 Doze를 우회하는 유일한 방법이지만, 남용 시 사용자에 의한 앱 차단과 권한 취소가 발생합니다.

제한 사항iOSAndroid
백그라운드 작업 시간 초과~30초(beginBackgroundTask)몇 분(JobScheduler)
무제한 백그라운드오디오, VoIP, 내비게이션, BluetoothForeground Service + 알림
절전Low Power Mode — 백그라운드 작업 비활성화Doze, App Standby, 배터리 최적화
예약BGTaskScheduler(iOS 13+)WorkManager(Android Jetpack)
재시작 후푸시 알림만WorkManager가 작업 유지
최대 실행 시간~30분(오디오)무제한(Foreground Service)

백그라운드 작업 모범 사례

첫 번째 규칙 — 백그라운드에서 리소스 소비를 최소화하세요. 대부분의 백그라운드 작업은 기기가 충전 중이고 Wi-Fi에 연결된 시간으로 연기할 수 있습니다. 조건이 있는 작업 예약에는 BGTaskScheduler(iOS)와 WorkManager(Android)를 사용하세요. 백그라운드에서 무거운 계산을 실행하지 마세요 — 배터리를 소모하고 CPU 스로틀링을 유발합니다.

두 번째 규칙 — beginBackgroundTask에 항상 expirationHandler를 지정하세요. 앱이 할당된 시간 내에 작업을 완료하지 않으면 시스템이 강제로 Suspended로 전환하거나 종료합니다. expirationHandler는 데이터를 저장하고 작업을 올바르게 종료할 마지막 기회입니다. Android에서는 WorkManager에서 setForegroundAsync를 사용하여 더 많은 시간이 필요할 때 일반 작업을 포그라운드로 변환하세요.

세 번째 규칙 — 시작 전에 백그라운드 작업 제한 사항을 확인하세요. iOS에서는 UIApplication.shared.backgroundTimeRemaining을 사용하여 남은 시간을 확인하세요. Android에서는 ActivityManager.isBackgroundRestricted()를 확인 — true인 경우 앱이 백그라운드 작업을 실행할 수 없으므로 설정에서 제한을 해제하도록 사용자에게 제안하세요. 이는 중요한 백그라운드 기능이 있는 앱(알람, 캘린더, 동기화)에 특히 중요합니다.

네 번째 규칙 — 실제 기기에서 백그라운드 작업을 테스트하세요. 시뮬레이터와 에뮬레이터는 실제 백그라운드 작업 제한을 재현하지 않습니다. iOS에서는 Xcode에서 Debug → Simulate Background Fetch를 사용하세요. Android에서는 재시작 후 WorkManager 테스트를 위해 adb shell am broadcast -a android.intent.action.ACTION_BOOT_COMPLETED를 사용하세요. 배터리가 부족한 기기에서의 실제 테스트가 대부분의 백그라운드 작업 문제를 드러냅니다.

swift
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("백그라운드 남은 시간: \(remaining)초")

        let task = UIApplication.shared.beginBackgroundTask { [weak self] in
            print("작업 시간 초과: \(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)
    }
}

코드는 남은 시간을 추적하고 식별자를 관리하는 백그라운드 작업 관리자를 보여줍니다. backgroundTimeRemaining은 강제 종료 전 초 수를 반환합니다 — 값이 무한대이면 앱이 제한 없이 실행 중입니다(오디오, 내비게이션). 관리자는 다른 이름으로 여러 백그라운드 작업을 시작하고 각각을 올바르게 완료할 수 있습니다. 이 접근 방식은 백그라운드 작업 누수를 방지하고 시스템이 종료되지 않은 작업으로 인해 앱을 종료하지 않도록 보장합니다.

자주 묻는 질문

iOS 앱이 영원히 백그라운드에서 실행될 수 있나요?

네, 제한된 카테고리에 대해서만 가능합니다: 오디오(AVAudioSession 카테고리 .playback), VoIP(PushKit), 내비게이션(allowsBackgroundLocationUpdates가 있는 CLLocationManager), Bluetooth(central background mode), 백그라운드 업데이트(BGTaskScheduler). 그 외 모든 경우는 최대 30초입니다. iOS 16+에서 Apple은 허용된 카테고리에도 요구 사항을 강화했습니다.

beginBackgroundTask와 BGTaskScheduler의 차이점은?

beginBackgroundTask는 백그라운드 전환 후 앱 수명을 약 30초 연장하는 동기 API입니다. applicationDidEnterBackground에서 호출됩니다. BGTaskScheduler는 시스템 트리거(시간, 위치, 콘텐츠 업데이트)를 통해 미래의 작업을 예약하는 비동기 API입니다. BGTaskScheduler는 Apple이 iOS 13+에 권장하는 최신 접근 방식입니다.

Android가 내 Background Service를 종료하는 이유는?

Android 8(API 26)부터 Background Service는 앱이 백그라운드로 전환된 후 몇 분 내에 종료됩니다. 해결책: 긴 작업에는 알림이 있는 Foreground Service, 지연 작업에는 WorkManager를 사용하세요. 설정에서 앱의 배터리 최적화를 확인 — 최적화된 경우 시스템이 백그라운드 작업을 연기하거나 취소할 수 있습니다.

iOS 시뮬레이터에서 Background를 테스트하려면?

Cmd+Shift+H를 눌러 홈 화면으로 이동합니다. Xcode에서 Debug → Simulate Background Fetch를 사용합니다. beginBackgroundTask를 확인하려면 콘솔(Shift+Cmd+C)을 열고 e UIApplication.shared.backgroundTimeRemaining을 호출합니다. Xcode 15+에서는 시뮬레이터의 Diagnostics 탭에서 Background Execution 시나리오를 사용할 수 있습니다.

Android의 process death란?

Process Death는 리소스 부족 또는 백그라운드 유휴 상태에서 시스템이 Android 프로세스를 종료하는 것입니다. iOS와 달리 Android에는 Suspended가 없습니다 — 프로세스는 살아 있거나(백그라운드 가능) 죽어(Not Running) 있습니다. Process Death는 OS의 정상적인 동작이며, 앱은 이후 SavedStateHandle, onSaveInstanceState 또는 DataStore를 통해 상태를 올바르게 복원해야 합니다.

요약

  • Background — 앱이 화면에 표시되지 않지만 코드 실행, Suspended(중단)와 다름
  • iOS — beginBackgroundTask(최대 30초) 및 미래 작업 계획을 위한 BGTaskScheduler
  • Android — 긴 작업에는 Foreground Service, 보장된 지연 작업에는 WorkManager
  • 제한 사항 — 두 플랫폼 모두 규칙 강화: Doze, Low Power Mode, App Standby
  • 저장 — applicationDidEnterBackground와 onStop이 Suspended/Not Running 전 마지막 기회
  • 예약 — BGTaskScheduler와 WorkManager가 조건부로 작동(Wi-Fi, 충전, 시간)
  • Foreground Service — 두 플랫폼에서 무제한 백그라운드 작업의 유일한 방법

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기