JobScheduler 使用指南

什么是JobScheduler?

JobScheduler 是Android 5.0之后提供的后台执行操作的API。简单点描述就是可以根据一系列条件,目前包括,时间,是否在充电,ContentProvider 是否改变等条件触发工作。这是和AlarmManager最大的区别,AlarmManager 只能在一个时间启动,不能根据机子时间启动。

会在什么情况下使用呢?

  • 用户拍了一张照片的时候需要触发相应的操作,这个时候就可以监听照片的ContentProvider ,发生改变就能触发我的操作。当然,这个同样适用于所有ContentProvider
  • 固定时间唤醒进行响应的操作
  • 需要设备空闲的时候进行图片的OCR识别保存信息
  • 需要设备空闲而且在充电的时候并且连接着WIFI的时候才能图片上传到服务器

....
根据JobInfo的API还有很多的组合

如何使用?

创建自己的JobService

要想使用JobScheduler ,必须先实现JobService。实现JobService就是实现onStartJobonStopJob这两个方法。在这个代码中,直接启动更新新闻的Service

public class SyncJobService extends JobService {
    @Override
    public boolean onStartJob(JobParameters jobParameters) {
        Timber.v("start job");
        Intent intent = new Intent(this, NewsUpdateService.class);
        intent.setAction(NewsUpdateService.ACTION_UPDATE);
        getApplication().startService(intent);
        return true;
    }

    @Override
    public boolean onStopJob(JobParameters jobParameters) {
        Intent intent = new Intent(this, NewsUpdateService.class);
        intent.setAction(NewsUpdateService.ACTION_STOP);
        startService(intent);
        return false;
    }
}

使用JobInfo配置任务

JobInfo.Builder API 介绍

构建方法

JobInfo.Builder (int jobId, 
                ComponentName jobService)

参数
jobId int:应用程序提供的这份工作的ID。后续调用取消,或以相同的jobId创造的就业机会,将更新具有相同ID的预先存在的工作。此ID必须是在同样的UID(而不仅仅是相同的封装)的所有客户端是唯一的。您将要确保整个应用更新的过程中是一个稳定的ID,所以可能不基于resource ID。
jobService ComponentName:您实现端点将接收来自的jobscheduler回调。此值绝不能是null。

addTriggerContentUri

API Level:24

JobInfo.Builder addTriggerContentUri(JobInfo.TriggerContentUri uri)

增加一个新的内容,将会使用ContentObserver监听这个URI,如果这个URI指向的内容发生改变,将会导致这个任务执行

参数
uri JobInfo.TriggerContentUri: 需要监控的内容,绝对不能为null。

setBackoffCriteria

API level:21

JobInfo.Builder setBackoffCriteria(long initialBackoffMillis, int backoffPolicy)

设置退货/重试策略。默认值为(30秒,BACKOFF_POLICY_EXPONENTIAL)。BACKOFF_POLICY_EXPONENTIAL就是指数上上的意思.如果不成功,我们将会在5个小时后回收这个任务。请注意,同时使用setRequiresDeviceIdle(boolean),当调用build()时, 将抛出异常。这是因为退休通常对这些类型的工作没有意义。

参数
initialBackoffMillis long: 当任务失败的时候多少秒重复一次
backoffPolicy int: BACKOFF_POLICY_LINEAR 或者BACKOFF_POLICY_EXPONENTIAL,代表重试策略,具体详情查看对应的文档,

note
讲解两个参数的区别

setClipData

API Level 24

JobInfo.Builder setClipData(ClipData clip,
                INT grantFlags)

设置一个ClipData与此相关的工作。

提供ClipData的主要目的是允许的URI的权限授予与该片段相关联的数据。确切的一种许可的授予执行通过指定grantFlags。

如果ClipData包含的意图项目,这些意图的任何拨款标志将被忽略。仅提供作为参数传递给该方法标志是推崇,将被应用到所有的URI或意图项在剪辑(或剪辑的子项)。

由于设置该属性是不持久的工作兼容,这样做会抛出IllegalArgumentException时 build()被调用。

参数
clip ClipData:新的剪辑设置。可为空以清除当前剪辑。
grantFlags int:所需的权限授予任何的URI。这应该是一个组合FLAG_GRANT_READ_URI_PERMISSION, FLAG_GRANT_WRITE_URI_PERMISSION和 FLAG_GRANT_PREFIX_URI_PERMISSION。

作用未明

setExtras

API Level 21

JobInfo.Builder setExtras(PersistableBundle演员)

可选的额外数据。这是持久形的,所以只能允许基本数据类型。

参数
extras PersistableBundle: 一个你想给任务额外数据的bundle,绝对不能为null

setMinimumLatency

JobInfo.Builder setMinimumLatency (long minLatencyMillis)

Specify that this job should be delayed by the provided amount of time. Because it doesn't make sense setting this property on a periodic job, doing so will throw an IllegalArgumentException when build() is called.

setOverrideDeadline

JobInfo.Builder setOverrideDeadline(long maxExecutionDelayMillis)

设定的期限是最大调度延迟。即使其他要求不符合,这项工作也会将在这个期限运行。因为这个参数对于periodic job 没有任何意义,这样做会抛出 IllegalArgumentException时 build()被调用。

参数
maxExecutionDelayMillis long

setPeriodic

JobInfo.Builder setPeriodic (long intervalMillis)

指定这个工作会在指定的间隔里面触发,在一个间隔里面不多于一次。你不能控制这个工作在这个周期中什么时候会被执行,只有可以保证在这个间隔里至多被执行了一次。与setMinimumLatency(long) or setOverrideDeadline(long)这两个方法一起使用将会抛出错误。

参数
intervalMillis long: 这个工作重复的毫秒间隔.
JobInfo.Builder setPeriodic (long intervalMillis, 
                long flexMillis)

指定此作业应以提供的间隔和flex重复。该工作可以在期限结束时的Flex长度窗口中随时执行。

参数
intervalMillis long: 工作的重,最小值由getMinPeriodMillis()决定。
flexMillis Flex被夹紧在至少为getMinFlexMillis()或5%的时间段,以较高者为准

setPersisted

JobInfo.Builder setPersisted (boolean isPersisted)

API LEVEL 21

设置是否在设备重新启动时持续执行此作业
需要RECEIVE_BOOT_COMPLETED权限。

参数
isPersisted True表示作业将被写入磁盘并在启动时加载。

setRequiredNetworkType

JobInfo.Builder setRequiredNetworkType (int networkType)

将一种网络的一些描述键入你的工作需要中。不调用此函数意味着网络是没有必要的,默认为 NETWORK_TYPE_NONE。请记住,调用此函数网络定义为你的工作严格要求。如果请求的网络不可用你的工作永远不会运行。见 setOverrideDeadline(long)来改变这种行为。

参数
networkType int 值是NETWORK_TYPE_NONE,NETWORK_TYPE_ANY,NETWORK_TYPE_UNMETERED,NETWORK_TYPE_NOT_ROAMING或NETWORK_TYPE_METERED。

setRequiresCharging

JobInfo.Builder setRequiresCharging (boolean requiresCharging)

指定要运行此作业的设备需要插电,默认为false。

setRequiresDeviceIdle

JobInfo.Builder setRequiresDeviceIdle (boolean requiresDeviceIdle)

指定要运行,工作需要的设备处于空闲模式。此默认为false。

空闲模式是由该系统中,这意味着该装置是不使用时,并且一直没有在使用一段时间后提供了一种松散的定义。因此,它是进行资源重工作的好时机。请记住,电池的使用仍然会被归结为你的应用程序,并在电池状态中显示给用户。

setRequiresStorageNotLow

API Level 26

JobInfo.Builder setRequiresStorageNotLow(boolean storageNotLow)

指定运行此作业时,设备的可用存储一定不会低。此默认为false。如果为真,工作只会在当设备不在低存储状态时运行,这通常是用户被赋予了“低存储”的警告。

参数
storageNotLow boolean: 设备的可用存储空间是否不能低。

setTransientExtras

JobInfo.Builder setTransientExtras (Bundle extras)

设置可选的临时附加功能。
因为设置此属性与持久作业不兼容,这样做会在调用build()时抛出IllegalArgumentException异常。

参数
extras Bundle:包含您希望调度程序为您提供的附加功能的软件包。 该值不能为空

setTriggerContentMaxDelay

API level 24

JobInfo.Builder setTriggerContentMaxDelay (long durationMs)

设置从第一次检测到内容更改到作业计划之前允许的最大总延迟(以毫秒为单位)。

参数
durationMs long:初始内容更改后的延迟,以毫秒为单位。

setTriggerContentUpdateDelay

API Level 24

JobInfo.Builder setTriggerContentUpdateDelay (long durationMs)

设置从内容更改检测到作业计划之前的延迟(以毫秒为单位)。如果在此期间有更多的更改,延迟将被重置为在最近更改时开始。

参数
durationMs long:最近内容更改后的延迟,以毫秒为单位。

总结