Background:基础知识,iOS 和 Android 应用程序在后台运行

作者: IT Sectr 发布日期: 2026-03-03 阅读时间: 10 分钟

Background — 应用程序生命周期中的一种状态,在此状态下它继续运行但不在屏幕上显示。我们解释 iOS 和 Android 后台工作的基础知识:限制、超时、通过 beginBackgroundTask、WorkManager 和 Service 进行的后台任务,以及正确处理 Background 的最佳实践。

要点

  • Background — 应用程序对用户不可见,但可以在有限时间内执行代码
  • iOS background task — beginBackgroundTask(expirationHandler:) 最多提供 30 秒完成工作
  • Android Service — Foreground Service 带有通知,用于长时间后台操作
  • WorkManager — Android 上推荐用于后台任务的 API,保证执行
  • 限制 — 两个平台都为了节省电池而收紧后台工作规则

Background — 后台状态的基础知识

Background — 应用程序的一种状态,在此状态下它继续存在于操作系统中,执行代码并消耗资源,但不在设备屏幕上显示。用户位于主屏幕、另一个应用程序中,或者设备屏幕已锁定。在 iOS 中,Background 在 Inactive 之后 — 转换链:Active → Inactive → Background。在 Android 中,onStop 表示 Activity 转换到 Background。

两个平台都对后台工作施加了严格的限制。iOS 提供了一个有限的时间窗口(通常为 30 秒)在进入 Background 后执行代码,之后应用程序将转换为 Suspended。Android 更加灵活:带有可见通知的 Foreground Service 可以无限期工作,但普通的 Background Service 限制为几分钟。开发者的关键任务 — 正确保存状态并通过系统后台任务 API 计划工作的继续。

系统可以在内存不足时随时终止后台应用程序。终止时,所有未保存的数据都会丢失。因此,在 applicationDidEnterBackground(iOS)或 onStop(Android)中保存状态至关重要。终止后,下次启动时应用程序从 Not Running 状态冷启动,并恢复已保存的状态。

Background 与 Suspended

区分 Background 和 Suspended 很重要。Background — 应用程序正在主动执行代码。Suspended — 应用程序在内存中但不执行代码 — 被冻结。在 iOS 中,应用程序在后台任务完成后从 Background 转换到 Suspended。在 Android 中没有 Suspended — 进程要么存在(包括后台),要么已终止(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 通过 beginBackgroundTask 启动一个后台任务,带有超时和 expirationHandler。同时注册 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 — WorkManager 用于带有条件(Wi-Fi、充电)的延迟任务。WorkManager 保证即使在设备重启后也能执行,并支持指数退避以进行重试。Foreground Service 需要在状态栏中有永久通知。

iOS 和 Android 后台工作的限制

两个移动平台都在不断收紧后台工作规则。在 iOS 中,每一代新操作系统都减少后台工作时间并增加新的限制。在 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、导航、蓝牙Foreground Service + 通知
省电Low Power Mode — 关闭后台任务Doze、App Standby、Battery Optimization
计划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 中 — adb shell am broadcast -a android.intent.action.ACTION_BOOT_COMPLETED 用于测试重启后的 WorkManager。在低电量设备上的真实测试 可发现大多数后台工作问题。

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)、导航(CLLocationManager 带有 allowsBackgroundLocationUpdates)、蓝牙(中央后台模式)、后台更新(BGTaskScheduler)。对于所有其他类别 — 最多 30 秒。在 iOS 16+ 中,Apple 甚至对允许的类别也收紧了要求。

beginBackgroundTask 与 BGTaskScheduler 有何不同?

beginBackgroundTask — 同步 API,用于在进入后台后将应用程序的生命周期延长约 30 秒。在 applicationDidEnterBackground 中调用。BGTaskScheduler — 异步 API,用于通过系统触发器(时间、位置、内容更新)计划将来的任务。BGTaskScheduler 是 Apple 为 iOS 13+ 推荐的现代方法。

为什么 Android 会杀死我的 Background Service?

从 Android 8(API 26)开始,Background Service 在应用程序进入后台几分钟后被终止。解决方案:对于长时间操作使用带有通知的 Foreground Service,对于延迟任务使用 WorkManager。在设置中检查您应用的 Battery Optimization — 如果已优化,系统可能会延迟或取消后台任务。

如何在 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 是操作系统的正常行为,应用程序应通过 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应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读