Background Execution —— 移动应用程序在前台不活动时执行代码的机制。如果没有这种机制,应用程序在最小化时会被系统暂停。根据 Apple, 2026 的数据,iOS 将后台时间限制为 30 秒,而 Android 则通过 WorkManager 和 Foreground Service 提供更灵活的方案。
要点
Background Execution —— 应用程序在用户将其最小化或切换到其他应用程序后继续执行代码的能力。如果没有特殊机制,移动操作系统会在进入后台几秒钟后将应用程序转换为 Suspended(暂停)状态,释放处理器和内存以供活动应用程序使用。
移动应用程序经历多个生命周期状态:Foreground(活动)、Background(后台)、Suspended(暂停)和 Terminated(终止)。Background —— 是应用程序可以在没有可见界面的情况下执行代码的唯一状态。iOS 和 Android 对此状态的持续时间和允许操作有不同的定义。
后台执行对于数据同步、内容下载、推送通知处理、后台定位和音频播放等任务是必需的。同步 —— 最常见的场景:应用程序无需用户参与即可向服务器发送数据或下载更新。
后台执行的限制由三个因素决定:能耗、设备性能和用户隐私。处理器和无线电模块(Wi-Fi、移动数据)消耗最多能量 —— 每个后台进程都会缩短电池续航时间。
Google 的研究表明,每 5 分钟执行一次后台任务的应用程序会将设备运行时间每天减少 20–30%。即使优化过的后台操作频率为每小时一次,如果超过两个这样的应用程序,也会产生显著影响。
每个后台应用程序都会占用运行内存。当内存不足时,系统会从内存中卸载应用程序,导致用户返回时重新启动。iOS 使用 Jetsam 算法 —— 一种在超出内存限制时强制终止后台进程的机制。Android 使用类似原理的 LMK(Low Memory Killer)。
从 Android 10 和 iOS 13 开始,系统要求应用程序声明后台工作的目的。Android 限制了后台启动 Broadcast Receiver。iOS 要求在项目的 Capabilities 中指定 Background Mode。用户可以在设置中禁用任何应用程序的后台执行。
| 操作系统 | 版本 | 限制 | 影响 |
|---|---|---|---|
| Android | 8.0 | IMPLICIT_BROADCAST 被禁止 | 67% 的后台广播被破坏 |
| 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 —— 任务在设备因维护而唤醒时在最近的维护窗口(Maintenance Window)中执行。
iOS 对后台执行采取更严格的方法。Background App Refresh —— 定期数据更新的主要机制。BGTaskScheduler —— 用于考虑系统状态来计划任务的 API。对于长时间操作,可以使用 Background Modes:audio、location、voip、fetch 和 processing。
Background App Refresh 允许应用程序每 15–30 分钟唤醒一次以进行数据同步。唤醒时间取决于用户行为 —— 系统分析用户打开应用程序的频率。用户可以在设置(设置 — 通用 — 后台应用刷新)中禁用单个应用程序的此功能。
从 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 模式限制 | 通过 URLSession 使用 background config |
| 后台定位 | Foreground Service + 许可 | Background Mode location + NSLocation |
| 后台音频 | 带有媒体通知的 Foreground Service | Background Mode audio + AVAudioSession |
WorkManager 适用于无论应用程序状态如何都必须执行的任务:数据同步、发送分析、处理队列。API 保证即使在设备关闭后也能执行 —— 任务在启动后重新计划。
BGTaskScheduler 适用于系统可以在任何方便时间执行的任务:下载新内容、更新小部件、清理缓存。不适合紧急操作 —— 如果设备处于 Doze 状态或电池电量低,系统会延迟任务。
常见问题
Background Execution —— 描述任何在后台执行的代码的通用概念。Background Modes —— 一种特殊的 iOS 机制,允许应用程序执行特定类型的后台操作:audio、geolocation、VoIP、fetch。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 上,PushKit 可用于 VoIP,Silent Push 可用于数据更新。在 Android 上 —— High Priority FCM 和 Notification Trampoline。通过 Foreground Service 的 WebSockets —— 实时应用程序的替代方案。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。