Android随笔-WorkManager 与 AlarmManager

Android WorkManager 与 AlarmManager 详解

一、WorkManager

是什么

WorkManager 是 Android Jetpack 组件,用于调度可延迟、可保证执行 的后台任务。它是 Google 推荐的后台任务首选方案

核心特性

特性 说明
保证执行 即使 App 被杀死、设备重启,任务依然会被执行(需满足约束条件)
自动选择 API 内部根据系统版本自动选择 JobScheduler(API 23+)、AlarmManager + BroadcastReceiver(API 14-22)或 Firebase JobDispatcher
约束条件 可设置网络状态、电量、存储空间等条件
链式任务 支持任务依赖(A 完成后执行 B)
观察状态 通过 LiveData/Flow 观察任务执行状态

适用场景

  • 同步数据到服务器(非即时)
  • 上传日志
  • 定期清理缓存
  • 图片压缩/处理

代码示例

kotlin 复制代码
// 定义 Worker
class UploadWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        // 执行后台任务
        val success = uploadData()
        return if (success) Result.success() else Result.retry()
    }
}

// 调度任务
val constraints = Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)  // 需要网络
    .setRequiresBatteryNotLow(true)                 // 电量充足
    .build()

val uploadWork = OneTimeWorkRequestBuilder<UploadWorker>()
    .setConstraints(constraints)
    .setInitialDelay(10, TimeUnit.MINUTES)  // 延迟10分钟
    .addTag("upload")
    .build()

WorkManager.getInstance(context).enqueue(uploadWork)

// 观察状态
WorkManager.getInstance(context)
    .getWorkInfoByIdLiveData(uploadWork.id)
    .observe(lifecycleOwner) { workInfo ->
        if (workInfo?.state == WorkInfo.State.SUCCEEDED) {
            // 任务成功
        }
    }

周期性任务

kotlin 复制代码
val periodicWork = PeriodicWorkRequestBuilder<SyncWorker>(
    15, TimeUnit.MINUTES  // 最小间隔15分钟(系统限制)
).build()
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
    "sync",
    ExistingPeriodicWorkPolicy.KEEP,
    periodicWork
)

二、AlarmManager

是什么

AlarmManager 是 Android 系统级服务,用于在精确时间点触发事件。它基于系统闹钟机制,即使设备休眠也能唤醒。

核心特性

特性 说明
精确触发 可精确到毫秒级触发(API 19 前),API 19+ 默认批量处理以省电
唤醒设备 可设置唤醒类型,在设备休眠时也能触发
系统级服务 直接对接 Linux 闹钟机制,独立于 App 生命周期
不保证执行 App 被强制停止后,闹钟会被清除(除非设置允许重启)

适用场景

  • 闹钟应用(必须在 8:00 响铃)
  • 定时提醒(日程、吃药)
  • 需要在精确时间执行的操作
  • 与 UI 强相关的定时任务

代码示例

kotlin 复制代码
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager

val intent = Intent(context, AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
    context, 0, intent, 
    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)

// 精确闹钟(API 23+ 需要 SCHEDULE_EXACT_ALARM 权限)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    alarmManager.setExactAndAllowWhileIdle(
        AlarmManager.RTC_WAKEUP,  // 使用 RTC,休眠时唤醒
        System.currentTimeMillis() + 60000,  // 1分钟后触发
        pendingIntent
    )
}

// 重复闹钟(不精确,系统会批量优化)
alarmManager.setInexactRepeating(
    AlarmManager.RTC_WAKEUP,
    System.currentTimeMillis(),
    AlarmManager.INTERVAL_HOUR,  // 每小时
    pendingIntent
)

接收器

kotlin 复制代码
class AlarmReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        // 闹钟触发,这里执行操作
        // 注意:onReceive 在主线程,耗时操作需启动 Service 或 WorkManager
    }
}

三、核心对比

维度 WorkManager AlarmManager
精确性 不保证精确时间(系统会批量优化) 可精确到毫秒(需权限)
保活能力 (App 被杀、重启后仍能执行) (App 被强制停止后闹钟清除)
唤醒设备 不会唤醒休眠设备(省电) 可配置唤醒休眠设备
约束条件 丰富(网络、电量、存储等)
任务链 支持复杂依赖链 不支持
观察状态 支持 LiveData/Flow 观察 不支持
系统限制 最小间隔 15 分钟 API 19+ 默认批量处理
推荐使用 后台数据同步、延迟任务 闹钟、精确提醒

四、底层原理简述

WorkManager

复制代码
App 进程 → WorkManager → 持久化到 Room 数据库 → 
系统 JobScheduler / AlarmManager + BroadcastReceiver → 
满足约束条件后 → 启动进程执行 Worker

关键点:任务信息持久化到 SQLite,即使进程被杀,系统服务仍能调度。

AlarmManager

复制代码
App → AlarmManagerService → 写入 Linux RTC 设备 → 
定时到达 → 内核唤醒系统 → 发送广播 → Receiver.onReceive()

关键点:直接对接 Linux 实时时钟,独立于 App 生命周期。


五、如何选择

复制代码
需要精确时间触发(闹钟、提醒)?  →  AlarmManager + 前台服务
需要保证执行但时间可灵活?        →  WorkManager
需要周期性后台同步?              →  WorkManager 周期性任务
需要在精确时间做后台数据处理?      →  AlarmManager 触发 → WorkManager 执行

最佳实践:AlarmManager 负责"准时叫醒",WorkManager 负责"可靠执行"。两者可以配合使用。


六、Android 12+ 的新限制

版本 限制
API 31+ SCHEDULE_EXACT_ALARM 变为特殊权限,用户需在设置中手动授予
API 33+ 引入 USE_EXACT_ALARM 权限(仅系统应用、闹钟应用可用)
Doze 模式 普通 AlarmManager 在 Doze 下被延迟,需使用 setAndAllowWhileIdle

这些限制进一步强化了 Google 的意图:精确闹钟只给真正需要它的应用(如闹钟),普通后台任务请用 WorkManager。

相关推荐
松仔log2 小时前
Java中级——组合和继承
android·java·开发语言
我命由我123456 小时前
Jetpack Compose - MaterialExpressiveTheme 与 MaterialTheme、ColorScheme
android·java·开发语言·java-ee·kotlin·android jetpack·android runtime
lilian2336 小时前
Harmony os 技术实战|拼豆制图06:收藏 ID、生成记录与重启恢复怎么不打架
android·java·数据库·harmonyos
2601_955759627 小时前
ClaudeAPI成本中心与业务标签设计指南
android·java·数据库
余衫马7 小时前
2026最新版!Android Studio 极速安装与配置指南
android·ide·android studio
AFinalStone7 小时前
Android 7系统异常问题排查(五)Framework层(下)—System Server崩溃
android·tombstone·系统异常
AFinalStone7 小时前
Android 7系统异常问题排查(八)系统追踪—Trace机制与性能诊断
android·系统异常
极客猴子11 小时前
Android录音转写频繁卡顿?多款APP长时间会议场景稳定性实测
android·人工智能·智能手机·飞书
Kapaseker11 小时前
Boolean 变量到底该怎么命名?
android·kotlin
AFinalStone11 小时前
Android 7系统异常问题排查(六)应用异常(上)—ANR机制全解
android·系统异常