是时候用JobService和WorkManager了
JobService 是Android针对后台任务优化推出的新组件,和 Servie 有着细致的关系又有很多不同。在需要执行后台任务的时候,面对JobService和Service,应该如何选择?
原理上的对比
Service
App通过Context发出请求,AMS接收请求后进行调度,通知App侧进行创建,开始,停止(或绑定,解绑)和销毁Service。
JobService
App通过 JobScheduler 接口发出创建JobService请求,JobSchedulerService接收到请求后解析任务执行的条件,通过AMS去依照任务的条件调度JobService的创建,绑定和解绑。不同于Service,JobService的开始,取消和停止等操作不是由App发出,由 JobSchedulerService 自行处理。
执行条件的对比
Service
Service的启动并没有什么特定的条件设置,如果说非要有什么具体的执行条件的话,就是App根据业务逻辑在适当的时候调用startService()或者bindService()。
JobService
JobService的执行需要至少一个条件。没有条件的JobService是无法启动的,在创建JobInfo的时候会发生异常。
启动时机上的对比
Service
App一旦通知Context去执行startService(),Service将得到运行。(使用bindService()的话,Service的运行取决于ServiceConnection的onServiceConnected()的回调)
JobService
JobService必须等待执行条件满足了才能被创建和开始。
执行时间上的对比
Service
onStartCommand()回调在UI线程,不宜执行耗时逻辑,否则可能造成ANR。
JobService
onStartJob()的回调也执行在UI线程,亦不宜执行耗时逻辑,否则可能造成ANR或者在超过8s后Job被强制销毁。并且,JobService里即便新起了工作线程,处理的时间也不能超过10min,否则Job仍会被强制销毁。
能否再启动的对比
Service
onStartCommand()返回START_STICKY可以告诉AMS在被停止后自动启动。
JobService
onStopJob()返回true,即可设置在被强制停止后可以再度启动。除了这些原理上的细微区别,那么你更应该关注实际应用上的不同。
实际应用
Service
适合需要常驻后台,立即执行,进行数据获取,功能维持等场景,比如音乐播放,定位,邮件收发等。
JobService
适合不需要常驻后台,不需要立即执行,在某种条件下触发,执行简单任务的场景。比如联系人信息变化后的快捷方式的更新,定期的更新电话程序的联系人信息,壁纸更改后去从壁纸提取颜色的后台任务。
总结
对比 | Service | JobService |
---|---|---|
内部原理 | AMS调度 | JobScheduler和AMS共同调度 |
执行条件 | 无明确要求 | 必须指定明确的执行条件 |
启动时机 | 立即启动 | 执行条件满足的时候启动 |
执行时间 | 不可执行耗时逻辑 | 8s的耗时限制外加10min的异步任务时长限制 |
再启动 | onStartCommand()返回START_STICKY | onStopJob()返回true |
实际应用 | 需要立即执行常驻后台的任务 | 不需要常驻在某种条件下执行 |
注意
基于Android针对后台执行任务的限制愈加严格,Service如果不提供可交互的UI(起码是通知级别),在启动几秒后将被系统杀掉。
还有基于DOZE MODE的考虑,进入省电模式之后可交互的Service仍面临被KILL的可能。
所以按照情况选择 JobService 或者基于JobService的 WorkMananger 是个不错的思路。