ZUI易入门Android之JobScheduler

在一篇关于网络优化的博文中发现了这个词。我们的项目中并没有使用到这个东西,但看了一下还是非常好用的,mark一下以后一定会用到吧。
贴官方文档,喜欢自学的可以过去看看
贴官方Demo,官方给出的例子也是非常好的,里面用到了Messager,以后会对它进行介绍。


这个类有什么用呢? 我们想象一种情景:
当且仅当设备在空闲状态, 并且使用wifi时, 自动下载新的Apk。

也许我们可能会这么做: 注册一个广播接受者 , 监听屏幕熄灭状态 , 熄灭之后检查网络状态 , 然后再在广播接受者中启动一个服务去下载新的apk。可以是可以,但是这个会不会过于复杂了。而且如果出现需求变更......
比如希望在特定情况下再启动事务,比如说延迟若干时间之后,或者等手机空闲了再运行,这样一方面不会在系统资源紧张之时喧宾夺主,另一方面也起到削峰填谷提高系统效率的作用。对于这些额外的条件要求,Service并不能直接支持,往往需要加入其他手段,才能较好地满足相关的运行条件

  1. 对于延迟时间执行,通常考虑利用系统的闹钟管理器AlarmManager进行定时管理
  2. 对于是否联网、是否充电、是否空闲,一般要监听系统的相应广播,常见的系统广播说明如下:
  • 网络状态变化需要监听系统广播android.net.conn.CONNECTIVITY_CHANGE;
  • 设备是否充电需要监听系统广播Intent.ACTION_POWER_CONNECTED也就是android.intent.action.ACTION_POWER_CONNECTED;
  • 设备是否空闲需要监听系统广播Intent.ACTION_SCREEN_OFF也就是android.intent.action.SCREEN_OFF;

Android从5.0开始,增加支持一种特殊的机制,即任务调度JobScheduler,该工具集成了常见的几种运行条件,开发者只需添加少数几行代码,即可完成原来要多种组件配合的工作,使代码变得更加优(牛)雅(x)。

认识一下必须要用的工具

  1. JobScheduler: 任务调度器
  2. JobInfo : 任务概要信息
  3. JobService: 任务服务,描述具体逻辑

简单使用JobScheduler

  1. 创建JobService
    我们具体的业务逻辑还是要写在jobService中的, 所以自定义一个服务继承自JobService 并重写两个抽象方法

onStartJob:在任务开始执行时触发。返回false表示执行完毕,返回true表示需要开发者自己调用jobFinished方法通知系统已执行完成。
onStopJob,在任务停止执行时触发。

  1. Activity中配置JobInfo
    JobInfo是从来描述任务的执行时间,条件,策略等一系列的行为,使用Builder模式来获取实例,这里摘一下官方给出的代码
JobInfo.Builder builder = new JobInfo.Builder(mJobId++, mServiceComponent);

        String delay = mDelayEditText.getText().toString();
        if (!TextUtils.isEmpty(delay)) {
            //设置至少延迟多久后执行,单位毫秒.  
            builder.setMinimumLatency(Long.valueOf(delay) * 1000);
        }
        String deadline = mDeadlineEditText.getText().toString();
        if (!TextUtils.isEmpty(deadline)) {
            //设置最多延迟多久后执行,单位毫秒。
            builder.setOverrideDeadline(Long.valueOf(deadline) * 1000);
        }
        boolean requiresUnmetered = mWiFiConnectivityRadioButton.isChecked();
        boolean requiresAnyConnectivity = mAnyConnectivityRadioButton.isChecked();
        if (requiresUnmetered) {
        //设置需要的网络条件,有三个取值:
        //JobInfo.NETWORK_TYPE_NONE(无网络时执行,默认)、
        //JobInfo.NETWORK_TYPE_ANY(有网络时执行)、
        //JobInfo.NETWORK_TYPE_UNMETERED(网络无需付费时执行) 
            builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
        } else if (requiresAnyConnectivity) {  
            builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
        }
        //是否在空闲时执行
        builder.setRequiresDeviceIdle(mRequiresIdleCheckbox.isChecked());
        
        //是否在充电时执行 
       builder.setRequiresCharging(mRequiresChargingCheckBox.isChecked());

        // Extras, work duration.
        PersistableBundle extras = new PersistableBundle();
        String workDuration = mDurationTimeEditText.getText().toString();
        if (TextUtils.isEmpty(workDuration)) {
            workDuration = "1";
        }
        extras.putLong(WORK_DURATION_KEY, Long.valueOf(workDuration) * 1000);

        builder.setExtras(extras);

        // Schedule job
        Log.d(TAG, "Scheduling job");
        JobScheduler tm = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
        tm.schedule(builder.build());
  • setRequiredNetworkType:设置需要的网络条件,有三个取值:-
    JobInfo.NETWORK_TYPE_NONE(无网络时执行,默认)、JobInfo.NETWORK_TYPE_ANY(有网络时执行)、JobInfo.NETWORK_TYPE_UNMETERED(网络无需付费时执行)
  • setPersisted:重启后是否还要继续执行,此时需要声明权限RECEIVE_BOOT_COMPLETED,否则会报错“java.lang.IllegalArgumentException: Error: requested job be persisted without holding RECEIVE_BOOT_COMPLETED permission.”而且RECEIVE_BOOT_COMPLETED需要在安装的时候就要声明,如果一开始没声明,而在升级时才声明,那么依然会报权限不足的错误。
  • setRequiresCharging:是否在充电时执行
  • setRequiresDeviceIdle:是否在空闲时执行
  • setPeriodic:设置时间间隔,单位毫秒。该方法不能和
    setMinimumLatency、setOverrideDeadline这两个同时调用,否则会报错“java.lang.IllegalArgumentException: Can't call setMinimumLatency() on a periodic job”,或者报错“java.lang.IllegalArgumentException: Can't call setOverrideDeadline() on a periodic job”。
  • setMinimumLatency:设置至少延迟多久后执行,单位毫秒。
  • setOverrideDeadline:设置最多延迟多久后执行,单位毫秒。
  • setBackoffCriteria: 退避策略 , 可以设置等待时间以及重连策略
  • build:完成条件设置,返回构建好的JobInfo对象。
  1. 声明MyJobService并将jobinfo加入, 执行
    就是上面代码的最后两句了, 这里也可以看到JobScheduler 的本质其实就是系统的服务。
Intent startServiceIntent = new Intent(this, MyJobService.class);
Messenger messengerIncoming = new Messenger(mHandler);
startServiceIntent.putExtra(MESSENGER_INTENT_KEY, messengerIncoming);
startService(startServiceIntent);

 

在Messager创建的时候就将一个handler作为参数来构造,之后作为extra来启动了服务。所以我们就能在服务中心的onStartCommand方法中获取到Messager的实例。接下来在服务的sendMessage方法中,也是直接用到了获取到的messager来发送消息,那肯定是发送到MainActivity传入的Handler中了,这里面的代码就不赘述了,都懂得。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值