🧩 WorkManager:兼容性优先的现代化方案
WorkManager是Jetpack组件,它在底层会自动选择最佳后端(包括JobScheduler),能兼容至API 14,并支持更灵活的任务链和约束。
使用步骤与示例:
-
添加依赖 在
app/build.gradle文件中添加:dependencies { def work_version = "2.8.0" // 使用当时最新稳定版本 implementation "androidx.work:work-runtime-ktx:$work_version" } -
定义一个
WorkerWorker是执行任务的单元。// 1. 定义你的Worker(例如一个图片压缩任务) class CompressImageWorker(context: Context, params: WorkerParameters) : Worker(context, params) { override fun doWork(): Result { // 这个方法在后台线程执行,无需担心主线程阻塞 val imagePath = inputData.getString("IMAGE_PATH") return try { // 执行实际的压缩工作... Log.d("WorkManager", "开始压缩图片: $imagePath") // 模拟耗时操作 Thread.sleep(2000) // 输出结果 val outputData = workDataOf("COMPRESSED_PATH" to "/sdcard/compressed.jpg") Result.success(outputData) // 任务成功完成 // 也可返回 Result.failure() 或 Result.retry() } catch (e: Exception) { Log.e("WorkManager", "压缩失败", e) Result.failure() } } } -
配置
WorkRequest并调度任务 你可以创建一次性或周期性的请求。// 2. 配置并调度一个一次性任务 fun scheduleOneTimeCompression(context: Context, imagePath: String) { // 创建输入数据 val inputData = workDataOf("IMAGE_PATH" to imagePath) // 设置约束条件 val constraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) // 需要网络 .setRequiresCharging(false) // 不需要充电 .setRequiresBatteryNotLow(true) // 电池不能处于低电量模式 .build() // 构建一次性工作请求 val compressionWork = OneTimeWorkRequestBuilder<CompressImageWorker>() .setInputData(inputData) .setConstraints(constraints) .setInitialDelay(10, TimeUnit.SECONDS) // 延迟10秒执行 .addTag("image_processing") // 给任务打标签,便于后续查询或取消 .build() // 提交给系统调度 WorkManager.getInstance(context).enqueue(compressionWork) } // 3. 调度一个周期性任务(例如每隔24小时备份一次) fun schedulePeriodicBackup(context: Context) { val constraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.UNMETERED) // 仅在Wi-Fi下 .setRequiresCharging(true) // 仅在充电时 .build() val periodicBackupWork = PeriodicWorkRequestBuilder<BackupWorker>( 24, TimeUnit.HOURS, // 重复间隔 15, TimeUnit.MINUTES // 柔性间隔:允许在执行窗口内有最多15分钟的延迟,增加批量执行机会以省电 ).setConstraints(constraints) .build() WorkManager.getInstance(context).enqueueUniquePeriodicWork( "unique_backup_work", // 唯一名称,确保同一时间只有一个此类任务 ExistingPeriodicWorkPolicy.KEEP, // 如果已存在同名任务,保留旧的,不调度新的 periodicBackupWork ) }
WorkManager高级特性:
- 任务链:可以按顺序或并行执行多个任务。
WorkManager.getInstance(context) .beginWith(listOf(workA, workB)) // 先并行执行A和B .then(workC) // 然后执行C .then(workD) // 再执行D .enqueue() - 观察任务状态:
WorkManager.getInstance(context).getWorkInfoByIdLiveData(compressionWork.id) .observe(this) { workInfo -> if (workInfo?.state == WorkInfo.State.SUCCEEDED) { val resultPath = workInfo.outputData.getString("COMPRESSED_PATH") // 更新UI... } }
💎 选择建议总结
| 特性 | JobScheduler | WorkManager |
|---|---|---|
| 最低API | API 21 (Android 5.0) | API 14 (Android 4.0) |
| 设计目标 | 系统级精准调度,电池优化 | 兼容性优先,使用简单,功能丰富 |
| 任务链 | 不支持 | 支持(顺序/并行) |
| 约束条件 | 基础约束(网络、充电) | 更丰富(电池是否充足、存储空间等) |
| 任务持久化 | 需要setPersisted和权限 | 自动处理 |
| 推荐使用场景 | 面向Android 5.0+,需要精确控制的系统级任务 | 绝大多数情况,尤其是需要兼容旧版本或使用复杂任务链 |
总的来说,对于现代应用开发,WorkManager通常是首选,除非你的应用有非常特殊的、仅针对新系统的精确调度需求。