Android使用WorkManager周期性执行后台任务
前言
下面是一个 使用 WorkManager 执行定时任务(周期性任务)的完整、可运行的简单示例,适用于 Android + Kotlin 项目。
场景:每 15 分钟从服务器拉取一次数据并打印日志(模拟同步操作)
注意
WorkManager 执行周期性任务,最短的时间间隔是15分钟。
添加依赖
在 app/build.gradle.kts(或 .gradle)中添加:
1 | dependencies { |
创建 Worker 类
1 | // SyncWorker.kt |
💡 使用
CoroutineWorker自动在后台线程执行,无需手动管理线程。
调度任务
在 Activity 或 Application 中调度任务
1 | // MainActivity.kt(或 App 启动时) |
监听任务状态(可选)
如果你想在 UI 上显示任务是否正在运行:
1 | WorkManager.getInstance(this) |
查看日志验证
运行 App 后,在 Logcat 中过滤 SyncWorker,你会看到:
1 | D/SyncWorker: 开始同步数据... |
注意:
- 首次调用会立即执行一次,然后每 15 分钟执行一次。
- 在 Doze 模式下(屏幕关闭+静止),实际执行可能延迟到系统维护窗口(约 15 分钟后)。
- 如果设备厂商(如小米、华为)限制后台活动,任务可能不执行——需引导用户关闭电池优化。
取消任务
1 | // 取消唯一周期任务 |
总结
步骤
- 添加
work-runtime-ktx依赖 - 创建
SyncWorker : CoroutineWorker - 用
PeriodicWorkRequestBuilder构建任务 - 用
enqueueUniquePeriodicWork提交(防重复) - 用
getWorkInfosByTagLiveData监听状态(可选)
注意
如需改成 一次性延迟任务,只需将
PeriodicWorkRequestBuilder改为OneTimeWorkRequestBuilder并调用setInitialDelay()。
常用方法
WorkManager.getInstance(Context) 返回的是 WorkManager 的单例实例,它是整个 WorkManager API 的入口点。通过这个实例,你可以调度任务、查询状态、取消任务等。
以下是 WorkManager 实例提供的主要方法分类及简要介绍(基于 androidx.work 2.10+ 版本):
任务添加
enqueue(WorkRequest)
作用:将一个或多个一次性任务加入队列。
参数:
OneTimeWorkRequest或其列表。注意:这个方法也可以添加周期任务,但是不建议。
enqueueUniqueWork(String uniqueWorkName, ExistingWorkPolicy policy, WorkRequest)
作用:以唯一名称提交一次性任务,避免重复。
策略:
REPLACE:替换旧任务KEEP:保留旧任务,忽略新任务APPEND:追加到现有任务链末尾
适用场景:防止用户多次点击按钮导致重复上传。
enqueueUniquePeriodicWork(String uniqueWorkName, ExistingPeriodicWorkPolicy policy, PeriodicWorkRequest)
- 作用:以唯一名称提交周期性任务。
- 策略:
REPLACE或KEEP(无APPEND)。 - 注意:周期任务最小间隔为 15 分钟。
周期性任务最短的间隔是15分钟
假如我们想每5分钟执行一次可以这样做
1 | workManager.cancelAllWorkByTag("TimingWorker") |
任务查询
所有查询方法都提供
LiveData和ListenableFuture两种版本(如getWorkInfos...()和getWorkInfos...LiveData())。
getWorkInfoById(UUID id)
- 获取指定 ID 的任务信息(同步或异步)。
getWorkInfosByTag(String tag)
- 根据标签查询所有匹配的任务。
getWorkInfosForUniqueWork(String uniqueWorkName)
- 查询通过
enqueueUniqueWork提交的唯一命名任务。
getWorkInfosByTagLiveData(String tag)等
- 返回
LiveData<List<WorkInfo>>,用于在 UI 中自动监听任务状态变化(推荐用于 Activity/Fragment)。
任务取消
cancelWorkById(UUID id)取消指定 ID 的任务。cancelAllWorkByTag(String tag)取消所有带指定标签的任务。cancelUniqueWork(String uniqueWorkName)取消通过唯一名称提交的任务。cancelAllWork()⚠️ 谨慎使用:取消所有由当前应用提交的 WorkManager 任务。
任务链构建
beginWith(OneTimeWorkRequest request)
- 开始构建一个任务链,返回
WorkContinuation。 - 后续可调用
.then(...).enqueue()。
beginWith(List<OneTimeWorkRequest>)
- 并行启动多个任务作为链的起点。
💡 示例:
1 workManager.beginWith(download).then(process).enqueue()
其他实用方法
pruneWork()清理已完成(成功/失败)且不再需要保留的内部数据库记录,释放存储空间。
createCancelPendingIntent(UUID id)创建一个
PendingIntent,可用于通知栏“取消”按钮直接取消任务(常与前台服务结合使用)。getForegroundInfo(UUID id)(仅限
ListenableWorker)获取前台服务所需的通知信息(用于长时间运行任务)。
注意事项
- 所有方法都需要传入有效的
Context(通常用applicationContext避免内存泄漏)。 - 不要缓存
WorkManager实例,每次都调用getInstance(context)即可(内部是单例)。 - 在 Android 15+ 中,后台任务受更严格限制,确保任务满足约束条件或使用前台服务 。
总结
| 方法类别 | 常用方法 | 用途 |
|---|---|---|
| 调度 | enqueue, enqueueUniqueWork |
提交一次性任务 |
enqueueUniquePeriodicWork |
提交周期任务 | |
| 查询 | getWorkInfoById, getWorkInfosByTag |
获取任务状态 |
...LiveData() |
实时监听状态变化 | |
| 取消 | cancelWorkById, cancelAllWorkByTag |
取消任务 |
| 链式 | beginWith(...).then(...).enqueue() |
构建依赖任务链 |
| 工具 | pruneWork, createCancelPendingIntent |
清理 & 取消辅助 |
建议优先使用 LiveData 监听状态 + enqueueUniqueWork 防重复 的组合模式。