欢迎大家关注我的掘金帐号
我会在那里定期更新最新版本的Android Framework源码模块分析~~
1.JobScheduler简介
JobScheduler是一个系统提供的框架,旨于在应用进程、而非系统进程内执行各种作业调度,其原理是启动通过bindservice的方式启动对应应用进程的service,并在Service中进行作业。在执行一个Job时,将会使得系统持有一个WakeLock锁,以防止系统休眠进入Suspend。
在创建一个作业时,会设置多个约束条件,比如可以指定特定的网络、是否只在充电时执行作业等,JobScheduler框架会根据这些约束条件,智能地执行作业,并尽可能对作业进行批操作和推迟,以防止频繁唤醒系统而影响功耗,还可以指定该Job的执行的截至期限。如果不指定一个作业的截至期限,那么该作业可能会在任意一个时刻运行,这取决于JobScheduler的内部队列。
2.JobScheduler组件
JobScheduler的使用比较简单,JobScheduler框架为应用提供了如下四个组件,通过这四个类的API可以让用户在应用中创建一个作业,并让系统对他进行调度。
- 1.JobScheduler
JobScheduler类负责将应用需要执行的作业发送给框架,以准备对该应用Job的调度。JobScheduler是一个系统服务,可通过如下方式获取:
JobScheduler mJobScheduler = (JobScheduler) Context.getSystemService(Context.JOB_SCHEDULER_SERVICE).
- 2.JobInfo
JobInfo是传递给JobScheduler类的数据容器,它封装了针对调用应用程序调度作业所需的各种约束,也可以认为一个JobInfo对象对应一个作业,JobInfo对象通过JobInfo.Builder创建。它将作为参数传递给JobScheduler:
mJobScheduler.scheduler(mJobInfo);
- 3.JobInfo.Builder
JobInfo.Builder是JobInfo的一个内部类,顾名思义,它就是用来创建JobInfo的Builder类。
JobInfo.Builder mBuilder = new JobInfo.Builder(id,new ComponentName(this,MyJobService.class));
mJobInfo = mBuilder.build();
- 4.JobService
JobService是一个继承于Service的抽象类,他作为系统回调执行作业内容的终端,JobScheduler框架将通过bindService()方式来启动该服务.因此,用户必须在应用程序中创建一个JobService的子类,并实现其onStartJob()等回调方法,以及在清单文件中对它授予如下权限:
<service android:name=".MyJobService"
android:permission="android.permission.BIND_JOB_SERVICE"/>
3.使用步骤
- 1.创建一个JobService的子类,作为系统回调终端:
public class MyJobService extends JobService {
@Override
public boolean onStartJob(final JobParameters params) {
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
return false;//返回false表示停止后不再重试执行
}
}
别忘了在清单文件中配置权限:
<service android:name=".MyJobService"
android:permission="android.permission.BIND_JOB_SERVICE"/>
- 2.创建JobInfo.Builder对象,为Job设置约束条件:
private ComponentName mServiceComponent;
//根据JobService创建一个ComponentName对象
mServiceComponent = new ComponentName(this, MyJobService.class);
JobInfo.Builder builder = new JobInfo.Builder(mJobId++, mServiceComponent);
builder.setMinimumLatency(1000);//设置延迟调度时间
builder.setOverrideDeadline(2000);//设置该Job截至时间,在截至时间前肯定会执行该Job
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);//设置所需网络类型
builder.setRequiresDeviceIdle(true);//设置在DeviceIdle时执行Job
builder.setRequiresCharging(true);//设置在充电时执行Job
builder.setExtras(extras);//设置一个额外的附加项
//...
- 3.获取JobScheduler实例
JobScheduler mJobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
- 4.开始调度Job
mJobScheduler.schedule(builder.build());//调度Job
mJobScheduler.cancel(jobId);//取消特定Job
mJobScheduler.cancelAll();//取消应用所有的Job
4.组件API
下面根据创建时机,对以上提到的四个组件类提供的API进行总结。
4.1.JobInfo.Builder
1.构造方法
JobInfo.Builder构造方法如下:
-
JobInfo.Builder (int jobId, ComponentName jobService)
int jobId:指定一个jobId,该Id可用来取消Job等。
ComponentName jobService:接收JobScheduler回调的终端ComponentName对象,应来自一个JobService对象。
2.成员方法
- setBackoffCriteria (long initialBackoffMillis, int backoffPolicy)
设置重新调度Job的策略
initialBackoffMillis:作业失败时最初等待的时间毫秒数;
backoffPolicy:重新执行一个job的执行策略
当调用JobService.JobFinished(params,true)、JobService.onStopJob()返回true时,都会根据该方法设置的策略重新调度.
对具有setRequiresDeviceIdle()的job设置该方法将引发异常。因为Doze状态下会对Job进行限制。
- setEstimatedNetworkBytes (long downloadBytes, long uploadBytes)
设置该job将执行的网络流量大小。
- setImportantWhileForeground (boolean importantWhileForeground)
设置该值为true,则说明该job在当app处于前台状态或白名单时是非常重要的。
- setMinimumLatency (long minLatencyMillis)
指定此job按提供的时间延迟。在定期job上,调用次方法将引发异常。
- setOverrideDeadline (longmJobScheduler maxExecutionDelayMillis)
设置此Job的最大延迟调度,无论任何条件,即使有条件不满足,Job也将在该截止时间前运行。在定期job上,调用次方法将引发异常。
- setPeriodic (long intervalMillis)
设置该Job为定期Job,即按照提供的间隔时间周期执行,一个周期内最多执行一次,如果设置该方法,则setMinimumLatency()和setOverrideDeadline()不可设置。
- setPeriodic (long intervalMillis, long flexMillis)
指定此作业应按提供的间隔和弹性重新执行。作业可以在周期结束时在具有flex长度的窗口中随时执行。
- setPersisted (boolean isPersisted)
设置是否在设备重新启动时保持此作业,此方法需要RECEIVE_BOOT_COMPLETED权限。
- setPrefetch (boolean prefetch):
- setRequiredNetwork (NetworkRequest networkRequest)
设置Job所需网络类型的详细描述,调用次方法后,将定义网络为该Job的严格要求,如果没有网络,那么该Job将不会执行。可以通过setOverrideDeadline()来更改此行为。
当Job在
jobservice.onStartJob(jobParameters)中执行时,请确保使用jobParameters.getNetwork()返回的特定网络.
- setRequiredNetworkType (int networkType)
设置Job所需网络类型的基本描述;
可选参数在JobInfo中,如:JobInfo.NETWORK_TYPE_UNMETERED
- setRequiresBatteryNotLow (boolean batteryNotLow)
指定该Job是否只在非低电量时运行,默认为false,如果指定为true,那么该job将仅仅在非低电量模式下运行。默认为false。
- setRequiresCharging (boolean requiresCharging)
指定该Job是否只在充电时运行此Job。默认为false。
- setRequiresDeviceIdle (boolean requiresDeviceIdle)
指定该Job是否只在DeviceIdle状态时运行此Job,即在交互状态时将不会运行。默认为false。
- setRequiresStorageNotLow (boolean storageNotLow)
指定此Job是否只在可用存储空间太低时运行,默认为false。
- setTransientExtras (Bundle extras)
设置临时附加项;
- setTriggerContentMaxDelay (long durationMs):
- setExtras (PersistableBundle extras)
设置额外附加项,如果需要携带其他基本类型参数,可以通过这个方法设置。
- build ()
创建JobInfo对象。
4.2.JobInfo
JobInfo中提供了几个用于方法参数的常量,以及和JobInfo.Builder中的setXXX()方法对应的getXXX()方法,此处就不再对这些方法进行说明,我们来看看它里面的一些常量的含义。
- BACKOFF_POLICY_EXPONENTIAL
以指数形式重新调度job
- BACKOFF_POLICY_LINEAR
以指数形式重新调度job
以上两常量作为JobInfo.Builder.setBackoffCriteria()的第二个参数使用,指定重新调度Job的策略。
- DEFAULT_INITIAL_BACKOFF_MILLIS
当重新执行一个job时,默认退让毫秒数(30s),JobInfo.Builder.setBackoffCriteria()的第一个参数.
- MAX_BACKOFF_DELAY_MILLIS
当重新执行一个job时,最大退让(延迟)毫秒数。
- NETWORK_TYPE_ANY
设置该值时,表示对应Job需要网络连接
- NETWORK_TYPE_CELLULAR
设置该值时,表示对应Job需要网络连接,且为蜂窝网络
- NETWORK_TYPE_NONE
默认值,表示该Job对网络连接无要求
- NETWORK_TYPE_NOT_ROAMING
设置该值时,表示对应Job需要网络连接,且为非漫游网络
- NETWORK_TYPE_UNMETERED
设置该值时,表示对应Job需要网络连接,且为WIFI(非计量)
以上这些NETWORK_TYPE_XXX值,作为方法JobInfo.Builder.setRequiredNetworkType()的参数使用,用于指定一个Job是否需要特殊网络条件。
4.3.JobScheduler
1.实例化
在上面已经说过了,JobScheduler是一个系统服务,通过如下方式获取其实例:
Context.getSystemService(Context.JOB_SCHEDULER_SERVICE).
2.成员方法
- cancel (int jobId)
取消指定的Job,并将忽略JobService.onStopJob()的返回值。
- cancelAll ()
取消该应用已调度的所有的Job。
-
int enqueue (JobInfo job, JobWorkItem work)
-
List getAllPendingJobs ()
获取应用程序已调度的所有Job。
- JobInfo getPendingJob (int jobId)
查找指定Job的描述信息。
- int schedule (JobInfo job)
开始调度一个Job,将使用JobInfo替换相同JobID中的所有信息,如果该Job正在运行,将会停止它。该方法返回值为RESULT_FAILURE or RESULT_SUCCESS,表示调度成功或失败。
3.常量
- RESULT_FAILURE
在调用schedule()时,提供参数无效时将返回该值。
- RESULT_SUCCESS
在调用schedule()时,如果成功调度将返回该值。
4.4.JobService
JobService是JobScheduler最终回调的端点,JobScheduler将会回调该类中的onStartJob()开始执行异步任务。该类是一个抽象类,用户必须继承JobScheduler实现一个类,并在配置文件中授予权限:
<service android:name="MyJobService"
android:permission="android.permission.BIND_JOB_SERVICE" >
...
1.成员函数
- onStartJob (JobParameters params)
当Job开始执行时,将回调该方法,因此该方法中为所执行的内容,该方法执行在应用主线程中。当该方法执行完毕后,如果返回true,那么也就意味着Job将一直处于激活的状态,依旧持有WakeLock锁;如果返回false表示该Job完成后,将不会再继续进行,释放WakeLock锁。
如果返回true,有如下三种方式结束该Job的执行:
1.调用JobFinished()方法通知系统已经完成其工作;
2.调用cancel()方法取消该Job,此时将回调onStopJob()方法;
3.如果没有任何处理,JobSchedulerService中将在600s后回调onStopJob()方法,并在8s后结束该Job的执行。
因此,如果onStartJob()执行完毕后,不再需要重复执行,则返回值更推荐使用false,当执行完毕任务后,将立即释放WakeLock锁,从而更好地优化功耗。
- onStopJob (JobParameters params)
如果在调用前JobFinished()系统停止该Job,则将回调该方法。比如在执行该Job过程中约束条件不满足导致停止了,这种情况下将回调该方法,然后将释放WakeLock锁。该方法返回true,则表示是否需要根据该Job创建时提供的重新执行策略重新调度该Job。返回false,则表示该job完全停止。
- jobFinished (JobParameters params, boolean wantsReschedule)
params:job所携带的参数
wantsReschedule:是否需要重复执行
该方法需要用户手动调用,以通知作业调度器已经完成该Job工作,系统收到调用信息后,将释放执行外Job时的WakeLock锁。
参数
wantsReschedule如果设置为true,将根据setBackbackOffCriteria()设置的执行策略进行调整。这种情况下,当重新调度作业时,最初的初始需求将被保留。
4.5.JobParamters
用来配置Job的参数容器,也就是说JobParamters有该Job的所有配置参数,因此它提供了多个getXXX()方法可以获取这些参数。JobParamters参数无需用户自行创建,系统将会创建完成,并作为JobService中回调函数的参数。
在JobService的
onStartJob(JobParamters)和onStopJob(JobParamters)中,JobParamters做为参数使用。
示例
Github:https://github.com/jeraon/jobscheduler
Google官方Sample:https://github.com/googlesamples/android-JobScheduler/#readme
本文介绍了Android 9.0中的JobScheduler,它是一个用于作业调度的系统服务,能智能地根据约束条件执行作业。文章详细讲解了JobScheduler的组件,包括JobScheduler、JobInfo、JobInfo.Builder、JobService和JobParameters,以及它们的使用步骤和API。还阐述了如何创建JobService子类、设置作业约束以及如何调度Job。


被折叠的 条评论
为什么被折叠?



