JobService和JobScheduler

       Google在Android 5.0中引入JobScheduler来执行一些需要满足特定条件但不紧急的后台任务,APP利用JobScheduler来执行这些特殊的后台任务时来减少电量的消耗,使用JobScheduler的时候需要把待执行的后台任务封装到JobService中提交。

       JobService继承自Service,并且是一个抽象类。在JobService中有两个抽象方法onStartJob(JobParameters)onStopJob(JobParameters)onStartJob在JobService被调度到的时候会执行,我们只需要继承JobService然后重写onStartJob方法,并在里面执行我们的后台任务就可以了。

public class MyJobService extends JobService {
    @Override
    public boolean onStartJob(JobParameters params) {
        return false;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        return false;
    }
}

       当任务开始时会执行onStartJob(JobParameters params)方法,这个方法返回一个boolean值。如果返回值是false,系统假设这个方法返回时任务已经执行完毕。如果返回值是true,那么系统假定这个任务正要被执行,这里就是我们需要自己写的任务执行逻辑了。当任务执行完毕时你需要调用jobFinished(JobParameters params, boolean needsRescheduled)来通知系统。

       为什么我不设置 jobFinished(jobParameters,true)呢?这样不就重复执行了,这里确实是可以重复(应该说是重试)执行,但是只有是在特定场景下定时任务执行失败了,然后再次重复调度上次失败(跟上次失败的执行条件一致)的任务,而且这个调度周期是线性增长的,每次失败后下一次执行的时间间隔就会变长,所有不是执行间隔相同的定时任务。

       当系统接收到一个取消请求时,系统会调用onStopJob(JobParameters params)方法取消正在等待执行的任务。很重要的一点是如果onStartJob(JobParameters params)返回false,那么系统假定在接收到一个取消请求时已经没有正在运行的任务。换句话说,onStopJob(JobParameters params)在这种情况下不会被调用。需要注意的是这个job service运行在你的主线程,这意味着你需要使用子线程,或者一个异步任务来运行耗时的操作以防止阻塞主线程。

接下来我们创建JobScheduler

private void startJobScheduler(Context context){
        JobScheduler mJobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
        JobInfo.Builder builder = new JobInfo.Builder(jobId,new ComponentName(context,MyJobService.class));
        builder.setPeriodic(5000);//执行周期
        builder.setPersisted(true);//设备重启以后是否重新执行任务

        //以下约束条件要至少满足一个,否则调用JobInfo.Buidler的build方法时会抛异常IllegalArgumentException
        builder.setMinimumLatency(3000);//任务运行最少延迟时间
        builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);//任何网络环境下都可以执行
        builder.setOverrideDeadline(50000);//若到期还没有达到规定的条件则会开始执行
        builder.setRequiresCharging(false);//是否在只有插入充电器的时候执行
        builder.setRequiresDeviceIdle(false);//是否手机系统处于空闲状态下执行

        if(mJobScheduler.schedule(builder.build())== JobScheduler.RESULT_SUCCESS){
            List<JobInfo> jobInfos = mJobScheduler.getAllPendingJobs();
            if(jobInfos!=null && jobInfos.size()>0){
                for (JobInfo jobInfo:jobInfos){
                    Log.e(TAG,"任务:"+jobInfo.getId());
                }
            }
        }
    }

       Android7.0的源码系统默认设置了一个最小间隔时间15分钟,在获取执行间隔时,会先比较最小间隔时间和设置的间隔时间,取其中大的那个。所以setPeriodic设置时间小于15分钟是不会生效的。setPeriodic设置值大于15分钟,Android7.0与Android7.0以下的版本无区别,都是按照设置执行周期正常执行。如果项目中要使用了小于15分钟的执行时间周期,我们可以使用setMinimumLatency(设置任务执行的最小延迟)来达到绕过7.0系统的限制。

if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){
            builder.setMinimumLatency(5000);
        }else{
            builder.setPeriodic(5000);
        }

       如果你的应用想停止某个任务,你可以调用JobScheduler对象的cancel(int jobId)来实现;如果你想取消所有的任务,你可以调用JobScheduler对象的cancelAll()来实现。

最后一步了,在Manifest.xml文件里添加service

<service
            android:name=".MyJobService"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.BIND_JOB_SERVICE" />

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值