JobScheduler省电机制
1.前言
JobScheduler(任务调度器)是 Android 提供的一种任务调度机制,可以替代传统的 WakeLock 和 Alarm 来执行后台任务。那么,它们之间的区别是什么?JobScheduler 又有哪些特别之处呢?
1.1 WakeLock 和 Alarm 的局限性
WakeLock:用于保持设备唤醒状态,但每个应用的 WakeLock 是独立的,无法协调多个应用的任务执行时机。
Alarm:用于定时触发任务,但每个应用的 Alarm 也是独立的,可能导致设备频繁唤醒。
1.2 JobScheduler 的优势
系统级调度:JobScheduler 运行在操作系统层面,能够协调多个应用的任务执行时机,减少设备唤醒次数。
智能调度:JobScheduler 允许设置任务执行的时间窗口,系统可以根据设备的整体状态(如电量、网络条件等)智能调度任务,从而降低功耗。主要体现在TimerController的alarm对齐。
2.JobScheduler 的省电功能
2.1 传统方式的功耗问题
如果 100 个应用每小时都使用 WakeLock 或 Alarm 唤醒设备一次,由于这些任务的执行时机无法同步,设备在一个小时内会被唤醒 100 次!这种频繁的唤醒会显著增加设备的功耗。
2.2 JobScheduler 的优化机制
JobScheduler 是系统级别的任务调度器,能够统一管理多个应用的任务执行时机。通过智能调度,设备每小时的唤醒次数会显著减少。
2.2.1 时间窗口的灵活性
JobScheduler 允许开发者设置任务执行的时间窗口。例如,可以将任务的执行时间限制在 5 分钟后到 10 分钟之前。这种灵活性为系统提供了调整空间,使其能够更好地协调多个任务的执行时机,从而减少设备唤醒次数。
2.2.2 唤醒次数的降低
由于 JobScheduler 的智能调度机制,设备每小时的唤醒次数会大幅减少。具体减少到多少次无法精确预测,因为这取决于系统的调度策略和任务的时间窗口设置。但可以肯定的是,唤醒次数会显著低于传统方式。
2.3 省电效果
根据 2016 年 Google 开发者大会 的数据,如果所有应用都使用 JobScheduler API,设备的整体电量消耗可以降低 15% 到 20%。这种显著的省电效果得益于 JobScheduler 的系统级调度能力。
3.JobScheduler 服务启动触发选项详解
JobScheduler 是 Android 提供的一种灵活的任务调度机制,相比传统的 AlarmManager,它提供了更多的触发选项和优化策略。以下是对 JobScheduler 各种触发选项的详细分析。Android 的 JobScheduler 机制通过多个控制器类(如 AppIdleController、BatteryController、ConnectivityController 等)实现了对任务调度的精细化管理。结合最新的 Android 机制(如 App Standby、Doze 模式、任务优先级、任务配额等),开发者可以更高效地管理后台任务,同时优化设备的功耗表现。通过合理设置任务条件和优先级,开发者可以确保任务在系统省电机制下仍能正常运行,从而提升用户体验。
3.1网络状态
JobScheduler 允许开发者根据设备的网络状态来触发任务执行。以下是五种可选的网络条件:
NETWORK_TYPE_NONE(默认条件):
无论是否有网络连接,任务都会被执行。
NETWORK_TYPE_ANY:
需要任意一种网络连接(Wi-Fi 或蜂窝网络)才能执行任务。
NETWORK_TYPE_UNMETERED:
设备连接到非计量网络(如 Wi-Fi)时才会执行任务。
NETWORK_TYPE_NOT_ROAMING:
设备不在漫游网络时才会执行任务。
NETWORK_TYPE_METERED:
设备连接到计量网络(如蜂窝网络)时才会执行任务。
3.2电池状态
JobScheduler 支持根据设备的电池状态来触发任务执行。
3.2.1 充电状态
是否在充电时执行:
任务仅在设备充电时执行,默认值为 false。
3.2.2 电量状态
是否在电量充足时执行:
任务仅在设备电量高于 15% 时执行(默认阈值,可配置)。
3.3设备空闲状态
设备空闲时执行:
当设备处于空闲状态(如熄屏一段时间后),任务才会被执行。
默认空闲时间为 71 分钟(4260000 毫秒)。
唤醒窗口时间为 5 分钟(300000 毫秒),即在 71 至 76 分钟之间可能被执行。
这些参数可在配置中调整。
日志示例:
如果日志中出现 tag=com.android.server.ACTION_TRIGGER_IDLE,说明有任务在设备空闲时被执行。
3.4URI 改变时执行
URI 变化触发任务:
当应用添加了一个 URI 并监控其变化时,任务会在 URI 发生变化时执行。
如果添加了多个 URI,系统会按顺序处理。
注意:此条件不能与重复执行时间条件同时使用,否则任务设置无效。
示例:
如果监控了联系人的 URI,当联系人信息发生变化时,任务会被触发执行。
3.5重试方案
JobScheduler 提供了灵活的重试机制,开发者可以自定义重试策略。
3.5.1 默认重试间隔
系统默认重试间隔为 30 秒。
最小重试间隔为 10 秒。
最大重试间隔为 5 小时。
3.5.2 重试策略
指数增长方式(默认):
下一次重试时间按失败次数的指数倍增长。
公式:
retry_time = current_time + initial_backoff_millis * 2 ^ (num_failures - 1)
线性增长方式:
下一次重试时间按失败次数的倍数增长。
公式:
retry_time = current_time + initial_backoff_millis * num_failures
示例:
如果设置初始重试时间为 10 分钟:
指数增长:10 分钟 → 20 分钟 → 40 分钟 → 80 分钟……
线性增长:10 分钟 → 20 分钟 → 30 分钟 → 40 分钟……
3.6 时间控制
JobScheduler 提供了多种时间控制选项,以优化任务的执行时机。
3.6.1 最小延迟时间
最小延迟时间:
任务在条件满足后,仍需等待设定的最小延迟时间才会执行。
示例:
如果任务设置为在连接 Wi-Fi 后延迟 5 分钟执行,则任务会在连接 Wi-Fi 后 5 分钟才可能被执行。
3.6.2 最大延迟时间
最大延迟时间:
无论条件是否满足,任务在达到最大延迟时间时一定会被执行。
示例:
如果任务设置为在连接 Wi-Fi 后最多延迟 30 分钟执行,则任务会在 30 分钟时强制执行。
3.6.3 重复执行时间
重复执行时间间隔:
任务可以按设定的时间间隔重复执行,最小间隔为 15 分钟。
执行窗口时间:
任务在重复执行时间间隔内的某个时间窗口内执行,最小窗口时间为 5 分钟。
公式:
最大延迟执行时间 = 当前时间 + 重复执行时间间隔
最小延迟执行时间 = 最大延迟执行时间 - 执行窗口时间
示例:
如果设置任务每 60 分钟执行一次,执行窗口时间为 10 分钟,则任务会在 50 至 60 分钟之间执行。
3.7多任务调度优化
当多个任务设置了执行窗口时间时,系统会智能调整任务的执行时机,以减少设备唤醒次数,从而优化功耗。
示例:
假设有三个任务在 00:00 同时被调度:
任务 A:每 30 分钟执行一次,执行窗口时间为 10 分钟(20 至 30 分钟)。
任务 B:每 15 分钟执行一次,执行窗口时间为 5 分钟(10 至 15 分钟)。
任务 C:每 40 分钟执行一次,执行窗口时间为 12 分钟(28 至 40 分钟)。
调度优化:
如果任务 A 和任务 C 的执行时间有重叠,系统可能会将它们合并执行。
如果任务 B 的执行时间与任务 A 和任务 C 重叠,系统可能会将它们一起执行。
日志示例:
job.delay:表示任务被推迟执行(最小延迟)。
job.deadline:表示任务在最大延迟时间点被执行。
4.Job 服务与系统省电机制的交互
开发者可以通过 JobScheduler 手动设置应用的任务在网络状态、电池状态、设备空闲、URI 变化、时间控制等条件下的运行策略。然而,Job 服务的执行不仅受开发者设置的策略影响,还会受到系统级省电机制(如 Doze 模式 和 App Standby)的控制。以下是结合当前 Android 最新机制的详细说明。
4.1Doze 模式对 Job 服务的影响
Doze 模式是 Android 引入的一种深度省电机制,旨在设备长时间未使用时减少后台活动,从而延长电池续航时间。
4.1.1 Doze 模式的触发条件
设备处于静止状态(如放在桌面上)。屏幕关闭一段时间(默认约为 30 分钟)。
4.1.2 Doze 模式对 Job 服务的限制
网络访问限制:在 Doze 模式下,Job 服务无法访问网络,除非任务被标记为 豁免(exempt)。
任务执行延迟:Job 服务的执行会被推迟到设备的维护窗口(Maintenance Window)中。维护窗口通常每隔几小时才会开启一次。
豁免任务:如果任务被标记为 重要任务(如高优先级通知或紧急任务),系统可能会允许其在 Doze 模式下执行。
4.1.3 开发者适配建议
对于需要实时执行的任务,开发者可以通过 setExpedited(true) 将任务标记为 紧急任务,以绕过 Doze 模式的限制。
对于非紧急任务,建议设置合理的时间窗口,以适配 Doze 模式的维护窗口。
4.2App Standby 对 Job 服务的影响
App Standby 是 Android 引入的一种应用级省电机制,旨在限制不常用应用的后台活动。
4.2.1 App Standby 的触发条件
应用长时间未被用户主动使用(默认约为 24 小时)。
4.2.2 App Standby 对 Job 服务的限制
网络访问限制:处于 App Standby 状态的应用,其 Job 服务无法访问网络。
任务执行延迟:Job 服务的执行会被推迟到设备的充电状态或用户主动使用应用时。
豁免任务:如果任务被标记为 重要任务(如高优先级通知或紧急任务),系统可能会允许其在 App Standby 状态下执行。
4.2.3 开发者适配建议
对于需要频繁执行的任务,开发者可以通过 setImportantWhileForeground(true) 将任务标记为 前台重要任务,以绕过 App Standby 的限制。
对于非紧急任务,建议设置合理的时间窗口,以适配 App Standby 的限制。
4.3应用群组(App Buckets)对 Job 服务的影响
Android 引入了 应用群组(App Buckets) 机制,将应用分为不同的优先级组,以进一步优化资源分配和功耗管理。
4.3.1 应用群组的分类
Active:用户正在使用的应用。
Working Set:用户经常使用的应用。
Frequent:用户偶尔使用的应用。
Rare:用户很少使用的应用。
4.3.2 应用群组对 Job 服务的影响
任务执行优先级:高优先级群组(如 Active 和 Working Set)的应用,其 Job 服务更容易被系统调度执行。
任务执行延迟:低优先级群组(如 Frequent 和 Rare)的应用,其 Job 服务的执行可能会被延迟或限制。
4.3.3 开发者适配建议
对于需要实时执行的任务,开发者应尽量将应用保持在较高优先级群组中(如通过用户交互或高优先级通知)。
对于非紧急任务,建议设置合理的时间窗口,以适配应用群组的限制。