后台任务概览
本教程共 100 篇 · 第 73 篇 · 更新于 2026-07-28 · 约 7 分钟阅读
73. 后台任务概览
本节目标:搞清楚 Android 后台任务的三类划分,知道什么场景用协程、什么场景用 WorkManager、什么场景必须开前台服务,不再选错 API。
Android 在后台任务这块管得越来越严。从 Android 8 限制后台服务,到 Android 11 限制后台位置,再到 Android 14 前台服务分类限制,选错 API 轻则任务跑不起来,重则应用被 Google Play 拒审。这章先把全局图给你。
三类后台任务
官方把后台任务分成三大类:
1. 异步工作(Async Work)
应用在前台时需要并发执行的操作。比如点击按钮拉数据、计算一个复杂结果。这种任务生命周期跟应用可见状态绑定,应用一进后台就可能被停。
特点:
- 用户看得见、摸得着,操作完马上要给反馈。
- 任务一般几秒到几十秒。
- 应用退到后台不保证完成。
首选方案:Kotlin 协程。轻量、好取消、和 Jetpack 集成紧密。
2. 任务调度 API(Task Scheduling)
即使用户离开应用、应用被杀、设备重启,也要保证执行的任务。比如定时同步数据、上传日志、夜间清理缓存。
特点:
- 不依赖应用是否在前台。
- 可以延迟执行,可以设定条件(充电、联网、空闲)。
- 任务可能要几分钟到几十分钟。
首选方案:WorkManager。这是 Jetpack 提供的官方调度库,自动处理重启、重试、约束。
3. 前台服务(Foreground Service)
用户主动发起、必须立即执行、不能中断的任务。比如音乐播放、运动记录、导航。
特点:
- 用户明确感知,要有通知提示。
- 系统不会轻易杀掉,优先级高。
- 受系统限制多,Android 14 起要声明服务类型。
首选方案:Service + startForeground(),或者用 WorkManager 的前台服务模式。
决策树
按官方建议,先问自己两个问题:
问题一:任务是否需要在应用后台时继续运行?
不需要 -> 用协程,最简单。
需要 -> 看问题二。
举个例子,刷新朋友圈列表这种事,用户走了就别刷了,协程足够。
问题二:任务推迟或中断会不会影响用户体验?
会 -> 用前台服务,必须立即执行不打断。
不会 -> 用 WorkManager,延迟执行无所谓。
比如音乐播放,用户切到后台也得继续响,用前台服务。比如上传分析日志,凌晨充电时传都行,用 WorkManager。
异步工作:协程
协程是异步工作的首选,前面 Kotlin 章节已经讲过基础。在 Android 上用得最多的是 viewModelScope 和 lifecycleScope:
class MyViewModel : ViewModel() {
fun loadData() {
viewModelScope.launch {
val data = repository.fetch() // suspend 函数
_uiState.value = data
}
}
}
ViewModel 一销毁,viewModelScope 自动取消,所有子协程跟着取消,不会泄漏。
Note协程不是「后台任务」的通用方案。它只在应用可见时可靠运行。一旦应用进后台被系统回收,协程也跟着没了。
任务调度:WorkManager
WorkManager 适合「需要可靠执行」的任务,三种类型:
| 类型 | 周期 | 用什么 |
|---|---|---|
| 立即 | 一次 | OneTimeWorkRequest,可设加急 |
| 长时间运行 | 一次或周期 | Worker + setForeground() |
| 可延期 | 一次或周期 | PeriodicWorkRequest |
举个例子,每天凌晨同步用户数据:
val request = PeriodicWorkRequestBuilder<SyncWorker>(1, TimeUnit.DAYS)
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresCharging(true)
.build()
)
.build()
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
"daily_sync",
ExistingPeriodicWorkPolicy.KEEP,
request
)
设备重启后任务还在,WorkManager 帮你持久化到 SQLite。
WarningWorkManager 不是用来跑「立即响应」任务的。用户点了「上传图片」希望马上看到进度,这种情况要么协程(前台时),要么前台服务(切后台也要继续)。
前台服务
前台服务必须挂一个通知,告诉用户「应用正在做什么」。Android 8 起强制要求,不挂通知直接崩。
class MusicService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val notification = NotificationCompat.Builder(this, "music_channel")
.setContentTitle("正在播放")
.setSmallIcon(R.drawable.ic_music)
.build()
startForeground(1, notification)
// 开始播放...
return START_STICKY
}
}
WarningAndroid 14(API 34)起,前台服务必须声明服务类型(
mediaPlayback、location、dataSync等),在 manifest 里写android:foregroundServiceType,还要申请对应权限。漏一个就崩。
后台限制演进
了解下限制是怎么一步步收紧的:
- Android 6(API 23):Doze 模式,息屏后设备进入深度休眠,网络、任务被推迟。
- Android 8(API 26):后台服务限制,应用在后台不能 startService,要用 JobScheduler。
- Android 9(API 28):后台位置限制,应用在后台拿位置要单独申请权限。
- Android 12(API 31):前台服务启动限制,应用在后台不能启动前台服务(有豁免)。
- Android 14(API 34):前台服务类型声明,必须声明用途,每种类型限制使用时长。
- Android 15(API 35):进一步收紧前台服务超时和启动条件。
规律很明确:能不让你后台跑就不让你跑,能延迟就延迟。所以现代 Android 的后台任务策略是「能用 WorkManager 就用 WorkManager」,前台服务是最后选项。
替代 API
有些场景系统提供了更专用的 API,比前台服务效率高:
| 场景 | 推荐 API | 别用 |
|---|---|---|
| 大文件下载/上传 | 用户发起的数据传输(User-Initiated Data Transfer) | 数据同步前台服务 |
| 蓝牙配对 | CompanionDeviceManager | 已连接设备前台服务 |
| 视频播放 | 画中画模式 | 媒体播放前台服务 |
| 到达某地点触发 | 地理围栏 Geofencing | 持续跟踪位置的前台服务 |
| 精确时间触发 | AlarmManager | WorkManager |
Tip这些替代 API 大多是 Android 14+ 才有的,新项目尽量用,老项目做兼容。
AlarmManager
AlarmManager 适合「精确时间点」触发的任务,比如闹钟应用、日历提醒。和 WorkManager 的区别:
- AlarmManager 精确,能叫醒设备。
- WorkManager 不保证精确时间,受 Doze 影响。
- AlarmManager 适合「用户能感知的时间点」,比如 7 点闹钟。
- WorkManager 适合「宽松的时间窗口」,比如「一天内同步一次」。
Android 12 起,精确闹钟要申请 SCHEDULE_EXACT_ALARM 权限,普通应用默认不让用。
选型表
总结成一张表,按场景选:
| 场景 | 选什么 |
|---|---|
| 用户操作时拉数据、计算 | 协程 |
| 应用在前台时的并发操作 | 协程 |
| 切到后台也要继续的下载/上传 | 用户发起的数据传输,或前台服务 |
| 定时同步数据 | WorkManager(PeriodicWorkRequest) |
| 上传日志、埋点 | WorkManager |
| 音乐播放 | 前台服务(mediaPlayback 类型) |
| 运动记录轨迹 | 前台服务(location 类型) |
| 闹钟提醒 | AlarmManager |
| 到达地点推送 | Geofencing |
常见坑
- 协程当后台任务用:应用一进后台就被杀,任务没跑完。
- WorkManager 跑即时任务:调度有延迟,用户等不及。
- 前台服务不挂通知:Android 8+ 直接崩。
- 前台服务不声明类型:Android 14+ 直接崩。
- 后台启动前台服务:Android 12+ 默认禁止,要么用户在前台触发,要么走豁免。
- Doze 期间以为任务能跑:息屏一段时间后任务会被推迟到维护窗口。
小结
Android 后台任务三类:异步工作用协程、可靠任务用 WorkManager、立即不可中断用前台服务。先用决策树定位类别,再选具体 API。能用替代 API 就别用前台服务,系统能省电省内存。下一章我们深入协程,讲 Flow 和异常处理。