【Android P】 JobScheduler服务源码解析(一) —— 如何使用Job

最近Jobscheduler的使用不当导致不少问题,比如定时任务不生效或者冲突。归根结底是对Jobscheduler的使用不熟悉以及,其工作原理没有一个系统性的了解。本人也曾踩坑,所以下定决心好好熟悉Jobscheduler。

概述

在android开发中经?;嵊姓庋男枨?,开发者需要在稍后的某个时间点或者满足某个特定的条件时去执行某个任务,例如当设备开始充电,或者网络状态连接到wifi状态时执行某些推送通知的任务,jobscheduler就是用来处理这类场景的任务。

Jobscheduler的android在5.0上针对于降低功耗而提出来的一种策略方案,自 Android 5.0 发布以来,JobScheduler 已成为执行后台工作的首选方式,其工作方式有利于用户。应用可以在安排作业的同时允许系统基于设备状态、电源和连接情况等具体条件进行优化。JobScheduler 可实现控制和简洁性,谷歌推出该机制是想要所有应用在执行后台任务时使用它。 在之前的版本上,没有Job 这个服务,客户端代码如果需要实现类似的需求,必须要在客户端代码用alarm ,network, battery等服务来多次判断条件,以实现此类需求,对于App 开发者来说,其实是一个比较麻烦和复杂的代码逻辑。而job 的出现,很大程度上把此类条件判断逻辑放到服务端去判断,当所有限制条件满足时候,客户端触发job

如何使用jobscheduler

应用如果想使用JobScheduler API的话,首先需要创建自己需要执行的任务信息,创建任务的方法在谷歌官方文档上已经有详细介绍,这里只是放出一个实例:


JobInfo updateJob = new    JobInfo.Builder(UPDATEDB_JOB_ID, new ComponentName(context, TimedUpdateCleanUpDbJobService.class))

                      .setPeriodic(UPDATE_MIN_TIME)// 设置循环时间

                      .setPersisted(true)// 是否是持久化的job,如果是,开机后便会设置到系统中,需要RECEIVE_BOOT_COMPLETED权限

                      .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) // 需要非计费网络

                      .setRequiresDeviceIdle(true)//需要设备空闲

                      .build();

JobScheduler scheduler = getSystemService(Context.JOB_SERVICE);

scheduler.scheduler(updateJob);

上面的一个任务是在开机之后执行初始化的操作。其实并不需要延时1s,但是这里需要注意的一个点是JobScheduler所创建并执行的人物必须是带有条件限制的,不然是违背其初衷的,当你创建一个任务不做任何限制条件并且直接调用 scheduler.schedule(builder.build());去执行该任务是不可行的,会报以下的异常


java.lang.IllegalArgumentException: You're trying to build a job with no constraints, this is not allowed.

其次需要新建一个service,来继承JobService(与DreamService类似),而且必须重写其中的两个方法,分别是onStartJob(JobParameters params)和onStopJob(JobParameters params);

客户端job 的代码书写


public class MyJobService extends JobService {

public abstract boolean onStartJob(JobParameters params) { // 在任务开始执行时触发。返回false表示执行完毕,返回true表示需要开发者自己调用jobFinished方法通知系统已执行完成。

...

jobFinished();

}

public abstract boolean onStopJob(JobParameters params){  //在任务停止执行时触发。返回true 为重新调度,返回false 表示不会重新调度,job完全被停止了

...

}

}

当上面创建任务时执行到scheduler.schedule(builder.build()); 则开始准备执行任务,一旦设置满足条件,便会执行到onStartJob()方法,也就是在我们的任务应该具体事宜应该是放在onStartJob中去做的。

当任务执行完毕后要调用jobFinished()来通知系统。当系统受到一个cancel请求时会取消该任务(当该任务未执行将其在pending list删除,如果该任务正在执行则停止其任务)。

使用Jobscheduler还需要到AndroidManifest.xml中添加一个service节点让你的应用拥有绑定和使用这个JobService的权限。


<service android:name="com.example.apuser.jobtest.JobTestService"

    android:permission="android.permission.BIND_JOB_SERVICE" />

这里需要重点注意的是:这个job service运行在你的主线程,这意味着你需要使用子线程,handler, 或者一个异步任务来运行耗时的操作以防止阻塞主线程。

常见接口解释:


setRequiresBatteryNotLow(boolean) //是否需要电量充足

setRequiresCharging(boolean) //是否需要充电默认false

setRequiresDeviceIdle(boolean) //是否需要设备空闲,设备空闲是指设备没有在使用并且已经有一段时间没使用了

addTriggerContentUri(TriggerContentUri) //监听指定ContentUri,改变时才会触发任务,和周期性和持续性任务不兼容

setPeriodic(long) //是否是周期性任务,intervalMillis是执行的周期,每个周期最多执行一次,和setMinimumLatency和setOverrideDeadline不兼容,flextime = intervaltime

setPeriodic(long intervalMillis, long flexMillis) // flex 时间为窗口时间。最小窗口时间为5分钟()

setMinimumLatency(long) // 设置任务至少延迟多少时间才执行

setOverrideDeadline(long) // 任务执行的截止时间,如果到了该截止时间,其他条件不满足也会被执行

setRequiresStorageNotLow(boolean) //设置任务需要存储空间充裕条件

setPriority(int) // 设置优先级。越大优先级越高

setPersisted(boolean) // 是否是持续性任务,如果是,开机后会继续执行,但需要RECEIVE_BOOT_COMPLETED权限

总结

JobScheduler 虽然是在5.0上新增加的一个新服务,但是从L到M,N以及最新的O 上,谷歌Android也是在重点推荐使用该功能,并且在Android O 上谷歌还推出了一套Android vitals 计划,旨在提高Android 系统的功耗,性能,以及稳定性等相关指标,在对功耗上提出来的建议便是,非精确性的定时任务建议使用Job来代替Alarm,能更加准确的满足条件的执行你想要执行的任务。在Android O上JobScheduler更加完善了其条件控制,加上了低存储,低电量策略下的job运行限制,这里将在后面job服务解析中继续提到

?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351

推荐阅读更多精彩内容