JobScheduler之入门

4,213 阅读3分钟

文中的源代码版本为api23

JobScheduler入门

想想看,如果一个应用程序需要执行一些后台任务,你会怎么实现? AlarmManager? Service? 又或者是SyncManager?

今天我们来学习另一种解决方案:JobSchedulerJobScheduler是在Android 5.0添加的,它可以检测网络状态、设备是否充电中、低电量、低存储等状态,当所有条件都满足时就会触发执行对应的JobService来完成任务。同时具备了重试、定时执行、持久化任务(设备重启后可恢复任务)等功能。可谓是十分强大。 大家可以查看该视频或者该文章了解个大概。

JobScheduler的使用大致分为三步

  1. 创建JobService
  2. 创建一个JobInfo
  3. 获取JobScheduler系统服务执行任务

1 创建JobService

JobScheduler的原理大致是是通过监听手机状态,当条件满足时启动Service执行任务。 因此在使用JobScheduler之前,我们需要定义一个Service,当然并不是随随便便定义,而是需要派生自JobService。 只需要重写onStopJobonStartJob即可。

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的工作原理。