文中的源代码版本为api23
JobScheduler入门
想想看,如果一个应用程序需要执行一些后台任务,你会怎么实现? AlarmManager? Service? 又或者是SyncManager?
今天我们来学习另一种解决方案:JobScheduler
。
JobScheduler
是在Android 5.0添加的,它可以检测网络状态、设备是否充电中、低电量、低存储等状态,当所有条件都满足时就会触发执行对应的JobService
来完成任务。同时具备了重试、定时执行、持久化任务(设备重启后可恢复任务)等功能。可谓是十分强大。
大家可以查看该视频或者该文章了解个大概。
JobScheduler
的使用大致分为三步
- 创建
JobService
类 - 创建一个
JobInfo
- 获取
JobScheduler
系统服务执行任务
1 创建JobService
JobScheduler
的原理大致是是通过监听手机状态,当条件满足时启动Service
执行任务。
因此在使用JobScheduler
之前,我们需要定义一个Service
,当然并不是随随便便定义,而是需要派生自JobService
。
只需要重写onStopJob
和onStartJob
即可。
class DemoJobService: JobService() {
override fun onStartJob(params: JobParameters?): Boolean {
//do sth...
//这个返回值是有讲究的
//true表示Service的工作在一个独立线程中执行,工作完成之后需要调用jobFinish方法通知JobScheduler工作完成
//false表示Service的工作已经完成,JobScheduler收到通知之后会释放资源
return false
}
//该方法会在一些极端场景下触发
//比如当前的Job需要有Wifi连接的场景下才可执行,但是在执行期间
//用户关闭Wifi,那么就会触发该方法
override fun onStopJob(params: JobParameters?): Boolean {
//do sth...
//true表示需要进行重试
//false表示不再进行重试,Job将会被丢弃
return true
}
}
同时,在manifest
中注册时,还需要设置一个权限(否则会报错),如下
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
//...
<service android:name=".DemoJobService"
android:permission="android.permission.BIND_JOB_SERVICE"/>
</application>
2 创建JobInfo
JobInfo
是对任务的描述,比如说需要监听哪些状态、重试策略、任务执行时间、是否持久化等等。
JobInfo.Builder
的构造函数需要传入一个jobId
,是Job
的唯一标志,后续通过该jobId
来取消Job
。
通过Builder
模式构造JobInfo
。
val jobInfo = JobInfo.Builder(1, ComponentName(packageName, DemoJobService::class.java.name))
.setBackoffCriteria(1000,JobInfo.BACKOFF_POLICY_LINEAR) //重试机制
.setMinimumLatency(1000)//设置延迟时间
.setOverrideDeadline(10000)//设置最后期限,如果达到该时间点,Job还没被执行,那么会强制执行一次
// .setPeriodic(2000)//每隔2s执行一次,跟上面两个会冲突
.setPersisted(true)//持久化,就算手机关机,启动之后也可以恢复Job,需要RECEIVE_BOOT_COMPLETED权限
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)//设置Job依赖的网络类型
.setRequiresCharging(false)//是否要求设备处于充电状态
.setRequiresDeviceIdle(false)//是否要求设备处于空闲状态
.build()
3 执行任务
最后通过getSystemService
获取JobScheduler
服务执行任务就可以了
//执行任务
val jobScheduler = getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
jobScheduler.schedule(jobInfo)
//取消任务
jobScheduler.cancel(1)
4 最后
JobScheduler
上手还是比较简单的,由于本文是基于api23的源码,因此还有很多新功能没有在源码中展示出来,如setRequiresBatteryNotLow
(设置Job
对电量的要求)、setRequiresStorageNotLow
(设置Job
对存储空间的要求)等,大家有兴趣可以自己去了解一下。
后续,我会从源码角度分析JobScheduler
的工作原理。