一、JobScheduler 到底是什么?
说实话,我刚接触 Android 开发那会儿,对 JobScheduler 的第一印象就是——「又一个系统调度工具」。但用久了才发现,这玩意儿其实是 Google 给开发者挖的一口「良心井」。
JobScheduler 是 Android 5.0(API 21)引入的一套任务调度框架。它的核心思想很简单:把任务交给系统,让系统决定什么时候执行。
你可能会问:「我自己开个线程跑不行吗?」行,但代价很大。我见过太多应用因为后台任务写得糙,被系统一刀切掉。嗯,JobScheduler 就是来解决这个问题的。
1.1 它解决了什么问题?
说白了,JobScheduler 要解决三个核心痛点:
- 省电:系统会把多个 App 的任务合并到一起执行,减少 CPU 唤醒次数
- 避免滥用后台:防止 App 在后台偷偷跑任务,耗电又占内存
- 适配 Doze 模式:Android 6.0 开始,设备休眠后网络和 CPU 都会被限制,普通 Service 根本跑不起来
我记得有个项目,用户反馈「手机放一晚上,电量掉了 30%」。查了半天,发现是某个第三方 SDK 在后台疯狂轮询。换成 JobScheduler 后,电量消耗直接降到了 5% 以内。
1.2 核心工作流程
先看一张图,帮你快速理解 JobScheduler 的运作逻辑:
流程其实不复杂:你提交一个 Job,告诉系统「我想在充电且连 WiFi 的时候干某件事」。系统会把这些请求攒起来,等到条件满足时统一执行。
二、和 Service、AlarmManager 的对比
很多新手会问:「我有 Service 和 AlarmManager 就够了,为什么还要学 JobScheduler?」
这个问题我当年也问过。来,直接看对比表:
| 特性 | JobScheduler | Service | AlarmManager |
|---|---|---|---|
| 触发条件 | 网络、充电、空闲等组合条件 | 手动启动 / 绑定 | 指定时间 / 间隔 |
| 省电策略 | 系统统一调度,批量执行 | 无,常驻后台 | 可唤醒设备,耗电较高 |
| Doze 兼容 | 原生支持,自动适配 | Doze 下会被杀死 | 需特殊处理 |
| 保活能力 | 任务完成后自动结束 | 可长期运行 | 触发后执行短暂操作 |
| 适用场景 | 后台同步、日志上传、预加载 | 音乐播放、位置追踪 | 闹钟、定时提醒 |
2.1 为什么 Service 不适合做延迟任务?
你想想看,Service 一旦启动,只要你不调 stopSelf(),它就会一直活着。这在 Doze 模式下是致命的——系统会直接把你整个进程杀掉。
我曾经接手过一个项目,里面用 Service 做每 5 分钟一次的数据上报。结果呢?Android 8.0 以后,后台 Service 直接被限制,那个功能彻底废了。后来改成 JobScheduler,问题才解决。
2.2 AlarmManager 的局限性
AlarmManager 适合做「到点就干」的事,比如闹钟。但它有个问题:它只管时间,不管其他条件。
举个例子:你想在「连上 WiFi 且手机空闲」的时候下载一个大文件。用 AlarmManager 你只能设个时间,但到了时间如果没 WiFi,任务还是会触发,然后失败。JobScheduler 就不会——它会等到条件全部满足再执行。
三、一个最简单的例子
光说不练假把式。来看一段最基础的 JobScheduler 用法:
// 1. 构建 JobInfo
JobInfo jobInfo = new JobInfo.Builder(
JOB_ID,
new ComponentName(context, MyJobService.class)
)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) // 仅 WiFi
.setRequiresCharging(true) // 仅充电时
.setPeriodic(15 * 60 * 1000) // 每 15 分钟执行一次
.build();
// 2. 提交给系统
JobScheduler scheduler =
(JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
scheduler.schedule(jobInfo);
// 3. 定义 JobService
public class MyJobService extends JobService {
@Override
public boolean onStartJob(JobParameters params) {
// 在这里执行你的后台任务
// 返回 true 表示任务还在执行,系统会等你调 jobFinished()
new Thread(() -> {
doBackgroundWork();
jobFinished(params, false); // 任务完成,false 表示不需要重试
}).start();
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
// 系统强制停止任务时回调
// 返回 true 表示希望重试
return true;
}
}
四、什么时候该用 JobScheduler?
根据我的经验,下面这些场景用 JobScheduler 最合适:
- 数据同步:比如新闻 App 在 WiFi 下预加载文章
- 日志上传:等用户充电且连 WiFi 时上传崩溃日志
- 缓存清理:设备空闲时清理过期缓存
- 预下载:预测用户可能要看的内容,提前下载
五、小结
JobScheduler 说白了就是 Google 给开发者的一把「省电利器」。它把任务调度的主动权交给了系统,让系统根据当前电量、网络、设备状态来合理安排执行时机。
和 Service 比,它更省电;和 AlarmManager 比,它更智能。但也不是万能的——关键看你用对场景没有。
嗯,这一章先带你入个门。后面我们会深入源码,看看 JobScheduler 到底是怎么调度任务的,以及如何写出更高效的 Job。
公众号:蓝海资料掘金营,微信deep3321