4. WorkManager 架构总览

4.1 架构边界划分

WorkManager 并非简单的 API 封装,而是一个用于“可延迟、可可靠执行的后台任务”的完整调度平台。其架构边界明确拆分为三个层次:

  • API 接口层:对外暴露 WorkManager、WorkRequest、Worker、Observable 等消费端 API,隐藏调度细节。
  • 调度与约束引擎层:内部调度器(Scheduler)根据约束(网络、电量、空闲状态等)计算最佳执行时机,并通过委托模式分发至底层执行。
  • 存储与持久化层:使用 WorkDatabase(Room)持久化任务状态与约束,确保进程重启后恢复调度。
架构关键边界:WorkManager 不直接创建线程执行任务,而是将 Worker 实例的生命周期托管给 WorkExecutor(默认线程池),其核心调度决策完全基于数据库状态机与约束匹配引擎。

4.2 核心组件职责

组件 职责 生命周期 选型权衡维度
Worker 定义具体业务逻辑(如上传日志、同步数据)。必须实现 doWork() 方法,返回 ListenableWorker.Result。 一次任务生命周期:创建 → 执行 → 结束(成功/失败/重试)。 是否支持同步/异步;CoroutineWorker 可绕过底层线程池限制。
WorkRequest 配置任务的调度元信息:约束条件、去重策略、重试策略、延期时间。实体保存为数据库一行记录。 从 enqueue 到 all work 完成或取消。 OneTimeWorkRequest vs PeriodicWorkRequest 的选择影响刷新频率与电量平衡。
WorkManager 统一入口:enqueue、cancel、getWorkInfo、prune。内部持有数据库、调度器、约束追踪器。 应用进程存活期间常驻,超出进程重启可通过 WorkManager.initialize 恢复。 初始化时是否自定义 Configuration 决定底层线程池大小与日志级别。

4.3 调度链路设计

以下是一次标准 OneTimeWorkRequest 的调度与控制流:

  1. 提交入口:调用 WorkManager.enqueue(workRequest)。此方法立即将 WorkSpec、WorkTag、WorkProgress 写入 WorkDatabase,状态置为 ENQUEUED。
  2. 约束评估:WorkManager 启动所有已注册的 Scheduler(如 GreedyScheduler、SystemJobScheduler)。每个 Scheduler 遍历数据库,查询满足约束条件的 ENQUEUED 任务。
  3. 任务分派:满足条件的任务通过 WorkSpec 创建 Worker 实例,并提交至 WorkExecutor(默认 Executors.newFixedThreadPool)执行。
  4. 生命周期绑定:执行期间 Worker 持有 Context 与 WorkParameters,通过 setForegroundAsync 或 setProgress 向数据库写入中间状态。
  5. 结果处理:doWork() 返回后,WorkManager 将结果写回数据库(SUCCESS / FAILURE / RETRY),并触发 WorkContinuation 中后续任务或 WorkInfo 通知。

数据流与控制流可抽象为以下架构图:

WorkManager 架构总览:组件与调度链路 WorkManager 架构总览 Client (Activity/Service) WorkManager WorkDatabase (Room) enqueue(WorkRequest) 持久化 WorkSpec Scheduler 集合 GreedyScheduler / SystemJobScheduler 注册 Scheduler Constraint Tracker 网络/电量/空闲 查询 ENQUEUED 任务 约束满足通知 WorkExecutor (线程池) Executors.newFixedThreadPool(2) 提交 Worker 实例 Worker (doWork 执行) 执行 doWork 调度链路说明 1. Client 仅与 WorkManager 交互 2. 约束由 Tracker 监听,Scheduler 驱动 3. Worker 不感知调度,只关注业务逻辑

4.4 生命周期契约

WorkManager 对 Worker 实例的生命周期有严格托管:

  • 状态机路径:ENQUEUED → RUNNING → SUCCESS / FAILURE / RETRY。每个状态变更都伴随数据库写入。
  • 进程存活时:Worker 在线程池中执行,若进程被系统杀死,WorkManager 在下次初始化时读取未完成的任务状态,重新进入调度。
  • 前台服务托管:使用 setForegroundAsync() 时,WorkManager 自动创建 ForegroundService 并持有 ForegroundInfo,彻底规避传统前台服务生命周期管理混乱的风险。
生命周期风险点:CoroutineWorker 的 doWork() 是挂起函数,如果协程被取消(例如进程销毁),WorkManager 无法自动重启该任务,需要依赖数据库中的重试标记。必须正确使用 setForeground 或设置合理的 BackoffPolicy。

4.5 选型权衡与风险点

维度 WorkManager JobScheduler 风险点
任务持久化 默认实现,进程重启可恢复 依赖 JobInfo,系统可能清除未完成任务 WorkManager 数据库过大时可能影响启动性能
约束灵活性 提供 NetworkType、BatteryNotLow、StorageNotLow、Idle 等 6 种约束 类似约束集合,但缺少自定义进度状态 过多约束会增加调度延迟(最长可达数小时)
链式依赖 原生支持 beginWith / then 链式任务 需自行通过 JobInfo.EXTRA_DEPENDENCY 实现 链式任务中任一任务失败默认影响整条链
测试能力 提供 TestListenableWorker 与 TestDriver UT 困难,依赖 ShadowJobScheduler WorkManager 测试框架与实际调度器行为可能有偏差

4.6 落地步骤

  1. 定义 Worker 实现:继承 Worker 或 CoroutineWorker,在 doWork() 中编写任务逻辑,使用 setProgress 上报进度。
  2. 配置 WorkRequest:通过 OneTimeWorkRequestBuilder 或 PeriodicWorkRequestBuilder 设置约束、重试策略、标签。
  3. 获取 WorkManager 实例:明确是否使用自定义 Configuration(如最小日志级别、自定义线程池)。
  4. enqueue 任务:调用 workManager.enqueue(workRequest),通过返回的 WorkContinuation 或 LiveData 监听结果。
  5. 处理结果:在 Activity 或 ViewModel 中观察 workManager.getWorkInfoByIdLiveData(uuid),更新 UI。

4.7 验收标准

  • 正确性:任务在应用存活、进程重启、设备重启后均能按预期执行;约束满足后才触发执行。
  • 响应性:从 enqueue 到 RUNNING 的延迟在 500ms 以内(无约束条件下)。
  • 可观察性:WorkInfo 状态变化能通过 LiveData 或 WorkManager.getWorkInfosByTag 准确查询。
  • 可测试性:单元测试覆盖率超过 80%,包含约束变更、失败重试、取消等场景。
  • 无泄漏:WorkManager 生命周期结束后 Worker 线程池全部回收,无残留 Worker 实例。