JobScheduler介绍

JobScheduler

在自己的进程中调度各种作业
可以通过构建JobInfo来执行schedule(JobInfo)来执行一个job
当一个Job标准声明创建,会在Application的JobService中执行任务,可以通过JobInfo.Build来在服务组件中对你的Job实现业务

framework层在执行Job的时候智能化,并尽可能的批量并推迟他们,如果没有指定结束日期,它可以随时运行,具体取决于JobSchedule内部队列的状态

当Job在运行状态,在你的app中会持有系统的weakLock,处于这个原因,你不需要在其运行期间做任何唤醒处理

不需要初始化这个类,通过

1
Context.getSystemService(Context.JOB_SCHEDULER_SERVICE)

或者是

1
Context.getSystemService(Class)

获取

enqueue

Similar to schedule(JobInfo),但是允许进行现有job的入队,如果一个相同id的job入队,将会替换原来id的job,但是任何先入队的任务将保留在下次运行时分发,相同id的job也会在下次的运时进行分发。

官方强烈建议将所有入队的job用相同的jobinfo,系统会选择最佳的安排等待处理/正在运行的任务。如果job在上次作业中更改,系统需要关联新的job这会导致job失败

应该避免使用

1
JobInfo.Builder.setExtras(PersistableBundle)


1
JobInfo.Builder.setTransientExtras(Bundle)

系统会检测之前的JobInfo,并在JobInfo改变的某些情况下出现这些错误,而且在队列中不可以使用

1
JobInfo.Builder.setClipData(ClipData, int)

即使ClipData完全相同,也会视为不同的JobInfo

###getAllPendingJobs

getPendingJob

schedule

cancel


Job

getBackoffPolicy

获取返回协议返回值有常量线性级,指数级

getClipData

返回夹在中间的值

getClipGrantFlags

犯会ClipData授予的权限

getEstimatedNetworkUploadBytes

API 28 返回上传流量的预估值

getExtras

获取序列化的bundle数据

getFlexMillis

获取这个Job的弹性时间,只有在periodic Job的时候才有效,job可以在期末的弹性窗口中执行。

getid

与此job相关联的唯一id

getMinFlexMillis

获取periodic job的最小弹性时间,

getMinLatencyMillis

不会定期工作的job,设置一个延迟来执行job的时间

getRequiredNetwork

获取这个job的执行的网络类型

getService

获取job的服务断点

getTransientExtras

返回一个bundle

getTriggerContentMaxDelay

当content uri改变的时候,这个时间是scheduing job的最大时间

getTriggerContentUris

获取job的所有url为了调度job这个uris必须有所改变

isPeriodic

判断job是否在定期重复


JobBuilder

###public JobInfo.Builder (int jobId,ComponentName jobService)

jobid:必须是跨版本的唯一id,必须在客户端内是唯一的。
jobService:JobScheduler收到的回

addTriggerContentUri (JobInfo.TriggerContentUri uri)

通过ContentObserver监听的一个Uri,它的改变会导致job的执行,如果有一个uri与job关联,那么uri的改变才会影响job的执行
想要持续监听job,需要再JobService最近更改之前设置一个observer来监听相同的uri
这个操作与periodic 或者persist Job不兼容,执行会抛出异常

setBackoffCriteria (long initialBackoffMillis, int backoffPolicy)

  • initialBackoffMillis Job失败时候等待初始化的时间
  • backoffPolicy 回退协议

设置回退/重试协议。

setClipData (ClipData clip,int grantFlags)

提供ClipData的主要目的是允许授予与剪辑关联的数据的URI权限
任何在ClipData中Intent的flag将失效。只有这个方法中的flag生效,并将用于Clip中的所有uri或Intent

setEstimatedNetworkBytes(long downloadBytes, long uploadBytes)

  • downloadBytes 预估的下载量,是一个非负byte
  • uploadBytes 预估的上传流量,是一个非负byte

设置此作业将执行的网络流量的估计大小(以字节为单位)
当确切的流量大小不确定时,提供一个预估值
这只是反映了基本任务的流量,如果用JobWorkItem在创建他们的时候还需要定义每个Item的网络流量

setExtras(PersistableBundle) API28

包含附加的信息,该值不能为空

setImportantWhileForeground (boolean importantWhileForeground)API28

如果系统后台限制的话应该用这个flag,如果没有后台限制的话,这个flag失效

setMinimumLatency (long minLatencyMillis)

指定这个job应该延迟的时间,在periodic job设置这个没有意义抛出异常

setOverrideDeadline (long maxExecutionDelayMillis)

设置最大延迟的期限,即使其他条件不符合,job将会在这个截止时间去执行,在periodic job设置会抛出异常

setPeriodic (long intervalMillis)

  • intervalMillis 重复出现的间隔

指定该作业应该以提供的时间间隔重复出现,每个时期不超过一次。你无法控制在此间隔内何时执行此作业,
job设置了setMinimumLatencysetOverrideDeadline将会抛出错误。

setPeriodic (long intervalMillis,long flexMillis)

  • intervalMillis 重复出现的间隔
  • flexMillis 限制时间为getMinFlexMillis() 或者5%以他们较高为准。

任务可以在任何时间末的弹性窗口中执行

setPersisted (boolean isPersisted) 需要权限( RECEIVE_BOOT_COMPLETED )

  • isPersisted 设置job将写入磁盘并在加载时启动

设置重启磁盘的时候job是否保留

setPrefetch (boolean prefetch)

  • 设置为true表示将预取一下用户信息来改善用户体验

例如当存在可计量数据的时候,允许作业在计量网络上执行。
系统还可以用此flag与用户模式绑定,确保数据在用户启动应用程序前被预取

setRequiredNetwork (NetworkRequest networkRequest)API28

  • networkRequest

设置你job的网络具体描述,如果网络不可用,则job不会运行。
用setOverrideDeadline(long)来改变这条规则。调用了这个方法将会覆盖setRequiredNetwork的属性,通常你只会设置一个。

setRequiredNetwork (NetworkRequest networkRequest)

当您的作业在JobService.onStartJob(JobParameters)中执行时,请确保使用JobParameters.getNetwork()返回的特定网络,否则您将使用可能不符合此限制的默认网络。

setRequiredNetworkType(int networkType)

  • networkType

如果您的作业不需要网络连接,则不需要调用此方法,默认值为JobInfo.NETWORK_TYPE_NONE。

setRequiresBatteryNotLow(boolean batteryNotLow)

  • job在低电量的时候不执行?当用户出现低电量提示的时候,这个属性会生效。

setRequiresCharging (boolean requiresCharging)

  • job必须在充电的时候执行

电源插在usb上或者不是在墙上电源的时候,电源也可能消耗殆尽,这个也不会生效

setRequiresDeviceIdle (boolean requiresDeviceIdle)

  • requiresDeviceIdle job是否在交互的时候使用

true则job不会在设备运行的时候使用,表明设备没有在活动,并且有一段时间没有在使用

setRequiresStorageNotLow (boolean storageNotLow)

  • storageNotLow 设备的存储量不低

这通常指设备提示了用户的存储量低

setTransientExtras (Bundle extras)

  • extras 设置可选择的临时信息

不能再periodic job中设置,会抛出异常

setTriggerContentMaxDelay (long durationMs)

  • durationMs

设置从第一次检测内容改变到job schedule执行的最大延迟

setTriggerContentUpdateDelay (long durationMs)

  • durationMs

设置检测到内容到job 执行的延迟,如果job有修改,则延迟重新计算。


JobInfo.TriggerContentUri

表明job想触发改Uri修改的信息

常量:

FLAG_NOTIFY_FOR_DESCENDANTS value is 0x000001

uri修改的时候触发

对应于ContentResolver.registerContentObserver(Uri,boolean,ContentObserver)的notifyForDescendants。

构造函数

public JobInfo.TriggerContentUri (Uri uri, int flags)

  • uri 会触发的uri
  • flags 就是常量定义的那个

JobParameters

包含了设置/认证Job的属性

##方法

completeWork (JobWorkItem work)

  • work 你已经完成处理的工作

报告之前dequeueWork()的JobWorkItem情况,就是告诉系统你已经完成了,不需要返回信息了 ,如果这队列中的最后一个item那么完成它则不会完成它的工作,要实现这一点,你还需要调用dequeu()方法

如果你要进入排队工作,那么必须调用此方法,不要调用其他的方法否则你会失去这个job

dequeueWork()

从当前的运行的job中的JobParameters取得下一个JobWorkItem
当没有更多的工作可用并且所有先前离队的工作已完成时调用此方法将导致系统处理您的工作
不可以调用jobFinished(JobParameters, boolean)否则你可能丢失即将到来入队的JobWorkItem

一旦调用这个方法出队列,你必须调用completeWork(JobWorkItem)来告诉系统你已经完成了工作
job在所有队列出队的时候才会完成工作。否则在下一个出队之前必须完成每一个出队的工作。
如果你想要并行处理job,可以在完成之前的工作之前多次使用dequeueWork(),并且在你想让它结束的地方结束

如果作业在所有工作完成之前运行到其可用时间段的末尾,则会正常停止。应该从JobService.onStopJob(JobParameters)返回true以便重新安排作业,并且通过这样做,任何未完成和未完成的作业都将在下一次作业运行时重新排队。

describeContents ()

标识指定序列化实例封装的对象种类,例如,如果对象将在writeToParcel(Parcel,int)的输出中包含文件描述符,则此方法的返回值必须包含CONTENTS_FILE_DESCRIPTOR位。

getClipGrantFlags()

使用JobInfo.Builder.setClipData(ClipData,int)构造此作业时传入的剪辑授予标志。如果未设置,则为0。

getTransientExtras()

在使用JobInfo.Builder.setTransientExtras(android.os.Bundle)构造此作业时传入的瞬态额外值。这永远不会为空。如果你没有设置任何额外的东西,这将是一个bundle。

getTriggeredContentAuthorities()

这报告哪些内容管理机构已经触发了这项工作如果没有权威机构触发它 - 也就是说,由于某种其他原因(如截止日期过期)而执行的作业,它只会为空。
如果这是非空值,则可以使用getTriggeredContentUris()来检索已更改的URI的详细信息(只要该值未超过可报告的最大数量)。

JobService

jobScheduler回调的入口。
这是处理jobScheduled的异步请求的基类。你需要重写onStartJob方法,这是你实现工作逻辑的地方。
该服务在应用程序主线程上运行的Handler上执行每个传入作业,这意味着你必须将你的执行逻辑卸载到另一个线程/处理程序/AsyncTask中去。不这样做会导致阻止任何将来从JobManager回调 - 特别是onStopJob(android.app.job.JobParameters),这意味着通知您不再满足调度要求。

##变量
必须执行此项权限

PERMISSION_BIND

1
2
3
4
Job services must be protected with this permission:
<service android:name="MyJobService"
android:permission="android.permission.BIND_JOB_SERVICE" >
...

##方法

public final void jobFinished (JobParameters params,boolean wantsReschedule)

  • params 这个job的参数,在startService中设置的Params
  • wantsReschedule 如果应根据首次计划时指定的回退标准重新计划此作业,则为true;否则为假。

通知jobSchedule已经完成了工作,当系统收到这个消息的时候,会释放正在进行的唤醒锁。
你可以传递true来请求安排此job,这将适用于该工作的回退协议;当原始计划作业时,可以通过JobInfo.Builder.setBackoffCriteria(long,int)方法调整此策略,不管回退协议如何,job在最初的请求将会保留。

onStartJob (JobParameters params)

  • params
  • retrun boolean 如果您的服务将继续运行,请在适当时使用单独的线程为true.false表示已经停止运行

如果你想让job持续工作,那么返回true
如果这样做,那么作业将保持活动状态,直到您调用jobFinished(JobParameters,boolean)以告诉系统它已完成其工作,或者直到不再满足作业所需的约束
例如,如果使用setRequiresCharging(true)计划作业,则系统会立即暂停该作业,如果用户拔掉设备电源,作业的onStopJob(JobParameters)回调将被调用,并且应用程序将被期望关闭与该作业相关的所有正在进行的工作。

只要您的工作正在执行,系统就会代表您的应用程序拥有一个唤醒锁这个wakelock是在调用这个方法之前获得的,直到你调用jobFinished(JobParameters,boolean),或者在系统调用onStopJob(JobParameters)来通知你的作业过早关闭之后才会释放。
从此方法返回错误意味着您的工作已完成。该系统的工作唤醒锁将被释放,onStopJob(JobParameters)将不会被调用。

boolean onStopJob (JobParameters params)

  • 返回值 true表示要向JobManager表明是否希望根据作业创建时提供的重试条件重新计划此作业。false表示完全结束工作。

如果系统已确定您甚至在有机会调用jobFinished(JobParameters,boolean)之前必须停止执行您的工作,则调用此方法。

如果不再满足在计划时间指定的要求,则会发生这种情况。

JobWorkItem

使用JobScheduler.enqueue可以加入工作的工作单元。有关更多详细信息,请参阅JobParameters.dequeueWork。

#JobServiceEngine

这不适合常规应用程序使用,但允许构建在平台之上的框架创建自己的Service,以便与JobScheduler交互以及添加其他功能
如果您只是想正常执行作业,则应该查看JobService。

谢谢您的鼓励~