1. 持久化任务恢复场景分析
当应用在后台执行上传、数据库同步、日志压缩等耗时任务时,系统可能因内存不足杀进程,或用户主动重启设备。如果任务状态只保存在内存中,恢复后无从得知进度,可能导致数据重复或丢失。Room + WorkManager 的组合提供了持久化任务恢复的标准化方案:Room 存储任务元数据与进度,WorkManager 读取 Room 并重新调度未完成的工作。
1.1 关键中断场景对比
下表对比了四种典型场景下 WorkManager 与 Room 的协作行为:
| 场景 | WorkManager 行为 | Room 数据状态 | 恢复能力 |
|---|---|---|---|
| 正常执行 | Worker 按约束运行,完成后标记 SUCCESS | 任务状态更新为 COMPLETED | 无恢复需要 |
| 应用重启 | WorkManager 初始化后查询未完成的 WorkSpec | Room 中保留中间状态(如 PROGRESS=50%) | 自动恢复,Worker 从断点继续 |
| 进程被杀 | 系统重启延迟恢复,WorkManager 在下次启动时重新调度 | Room 任务记录完整,不存在脏数据 | 无需人工干预,数据不丢失 |
| 任务状态丢失 | WorkManager 无法得知之前进度,需依赖 Room 存储的自定义状态字段 | 若未持久化自定义字段,任务还原到起始点 | 需额外校验,建议存储幂等 |
设计要点:始终在 Worker 中通过 Room 更新任务状态,而非仅依赖 WorkManager 内置的 Result。因为 WorkManager 的 WorkSpec 在进程被杀后可能丢失自定义数据。
1.2 Room 数据库:任务的持久化锚点
Room 负责存储任务的元数据(ID、类型、进度、重试次数)和执行过程中产生的临时结果。一个典型的任务实体定义如下:
@Entity(tableName = "pending_tasks")
data class PendingTask(
@PrimaryKey val taskId: String,
val type: String, // "upload", "sync", "compress"
val progress: Int = 0, // 0-100
val status: String = "PENDING", // PENDING, RUNNING, COMPLETED, FAILED
val retryCount: Int = 0,
val nextRetryTime: Long? = null
)
通过 DAO 增删改查,Worker 可以在任何阶段持久化当前进度。即使进程被完全杀死,Room 文件仍在内部存储中,重启后即可读取。
1.3 WorkManager 调度与恢复流程
WorkManager 内部维护一个 SQLite 数据库(WorkDatabase),记录所有 WorkSpec 和 WorkProgress。当进程被杀重启时,WorkManager 会:
- 初始化时扫描 WorkDatabase 中状态为
ENQUEUED或RUNNING的 WorkSpec; - 根据约束(网络、充电等)重新将 Worker 加入调度队列;
- 在 Worker 的
doWork()中,主动查询 Room 中的PendingTask表,读取之前保存的进度和参数,继续执行。
关键代码片段——WorkManager 初始化与恢复触发:
// Application 初始化
WorkManager.initialize(this, Configuration.Builder()
.setMinimumLoggingLevel(android.util.Log.INFO)
.build())
// 恢复逻辑通常在 App Startup 或首次打开 Activity 时
val workManager = WorkManager.getInstance(application)
workManager.getWorkInfosByTagLiveData("restore_tasks")
.observe(owner) { workInfos ->
// 检查是否有未完成的 Worker,若有则同步 Room 中的任务
if (workInfos.any { it.state == WorkInfo.State.ENQUEUED }) {
restoreFromRoom()
}
}
1.4 完整恢复流程
下图展示了从任务创建到进程被杀再到恢复执行的完整数据流:
注意:进程被杀后,
doWork() 中正在运行的代码会被中断,再次执行时会重新进入该方法。务必在 onStopped() 或 Result.retry() 回调中保存现场到 Room,否则恢复后只能从头开始。通过上述分析可以看出,Room 提供了任务状态的可靠存储层,WorkManager 保证了调度生命周期的系统级恢复能力。二者结合,能够覆盖绝大多数业务场景下的任务持久化要求。