jobservice与jobchedule详解,以及如何应用

来源:互联网 发布:弱水三千网络歌手伴奏 编辑:程序博客网 时间:2024/06/14 03:46


Jobscheduleandroid5.0之后提供的机制。通过这种机制。可以让系统在某些特定环境下或固定时间间隔里,异步执行一些作业。

Android提供这种机制的目的就是为了优化电池。

 

Jobschedule可以设置在下面这些特定的的条件下调度:

固定周期唤醒

充电唤醒

设备空闲时唤醒

免费网络连接时唤醒

 

 

1Jobscheduler的方法

1 abstract void  cancel(int jobId)

杀死具体的jobinfo

2  abstractvoid  cancelAll()

杀死在这个包里注册的所有的jobinfo

3   abstractList<JobInfo> getAllPendingJobs() 

获得所有的jobinfo

4   abstractint  schedule(JobInfo job) 

注册一个jobinfo

2Jobinfo.builder的几个方法

1 JobInfo.Builder  setBackoffCriteria(long initialBackoffMillis,int backoffPolicy)

这个方法是设置重试机制的时间策略,有线性和指数增长两种方式。这个方法与jobFinished(params, true)有关。

两种方式

publicstatic final int BACKOFF_POLICY_EXPONENTIAL指数

retry_time(current_time,num_failures) = current_time + initial_backoff_millis * 2 ^ (num_failures - 1),num_failures >= 1

publicstatic final int BACKOFF_POLICY_LINEAR线性

Linearlyback-off a failed job. See setBackoffCriteria(long, int)retry_time(current_time, num_failures) = current_time + initial_backoff_millis* num_failures, num_failures >= 1

initial_backoff_millis系统默认为30秒,可以自己设置。最大的重试间隔为5个小时

 

2 JobInfo.Builder  setExtras(PersistableBundle extras)

设置额外的信息,可以在jobservice中获得到。

3 JobInfo.Builder setMinimumLatency(long minLatencyMillis)

设置最小的延迟时间

 

4 JobInfo.Builder  setOverrideDeadline(longmaxExecutionDelayMillis)

设置最大的延迟时间,一旦设置了这个属性,不管其他条件怎么样,jobinfo到了时间就一定会执行。

5 JobInfo.Builder  setPeriodic(long intervalMillis)

Specify that this job should recur with theprovided interval, not more than once per period.

这个就是周期性执行

6 JobInfo.Builder  setPersisted(boolean isPersisted)

手机重启后,还是会执行jobinfor

7 JobInfo.Builder  setRequiredNetworkType(int networkType)

设置在什么样的网络下启动jobinfo,有三种

和网络变化有关系的api

NETWORK_TYPE_ANY ,任意网络都可以

NETWORK_TYPE_NONE.默认的,有没有网络都执行

NETWORK_TYPE_UNME_TERED,无线网络接入

 

 

8 JobInfo.Builder  setRequiresCharging(boolean requiresCharging)

设置需要在充电的情况下才会启动jobinfo

9 JobInfo.Builder  setRequiresDeviceIdle(booleanrequiresDeviceIdle)

设备需要在空闲的时候,才会启动job

 

上述的几个情况是与的关系,而不是或的关系,要注意!!!

 

 

3JobInfo

public static final int BACKOFF_POLICY_EXPONENTIAL

指数,前面介绍过了

public static final int BACKOFF_POLICY_LINEAR

 线性 前面介绍过了

 public static final long DEFAULT_INITIAL_BACKOFF_MILLIS

 默认重试的第一次间隔为30

主要用在setBackoffCriteria(long,int)的第一个参数中

 

 publicstatic final long MAX_BACKOFF_DELAY_MILLIS

默认的最大的重试间隔为五个小时

 

 public static final int NETWORK_TYPE_ANY  有网

 

 public static final int NETWORK_TYPE_NONE 有网无网都可以

 

 public static final int NETWORK_TYPE_UNMETERED 无线网

4JobService

 

1 finalvoid jobFinished(JobParameters params,boolean needsReschedule)

告诉JobManager已经完成了工作,如果第二个参数为false,就是不需要重试这个jobinfo

第二个参数为true,相当于告诉系统任务失败,需要重试,而且与要遵守之前的jobinfo.

如果onstartjob()调用了这个方法,那么系统就不会再去回调onstopjob()方法,因为jobfinished()执行完后会直接把service destory

 

2abstract boolean onStartJob(JobParameters params)

一般我们的逻辑都是在这里面操作的,但是这个是主线程的,所以我们最好在子线程里面执行耗时操作。

返回false的话,jobfinish()中的true属性不在有用,也就是不再重试。只有返回true,jobfinish(true)才会有用。如果没有调用jobfinish Service会直接destory

一般都是返回true,表示还有任务要做。

3 abstract boolean  onStopJob(JobParameters params)

这个方法的回调很奇怪,我只验证了一种情况,就是onstartjob()中没有调用jobfinish(),然后把网络关掉,这时候就会回调这个方法。其他的我没去发现,贴上原话!!

一般都返回false.

 

This method is called if the system hasdetermined that you must stop execution of your job even before you've had achance to call jobFinished(JobParameters, boolean).

 

This will happen if the requirementsspecified at schedule time are no longer met. For example you may haverequested WiFi with setRequiredNetworkType(int), yet while your job wasexecuting the user toggled WiFi. Another example is if you had specifiedsetRequiresDeviceIdle(boolean), and the phone left its idle maintenance window.You are solely responsible for the behaviour of your application upon receiptof this message; your app will likely start to misbehave if you ignore it. Oneimmediate repercussion is that the system will cease holding a wakelock foryou.

 

然后这些就是api的简介,下面是谷歌给的demon中的用法。

Service必须在mainfest中这样配置。

 <service

           android:name=".service.MyJobService"

           android:permission="android.permission.BIND_JOB_SERVICE"

           android:exported="true"/>

 

设置jobinfo的代码

mainactivity中。

private ComponentName mServiceComponent;

 

publicvoidscheduleJob(View v) {

       JobInfo.Builder builder = new JobInfo.Builder(1,mServiceComponent);

 

           builder.setMinimumLatency(Long.valueOf(delay)* 1000);

           builder.setOverrideDeadline(Long.valueOf(deadline)* 1000);

           builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);

           builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);

 

       builder.setRequiresDeviceIdle(mRequiresIdleCheckbox.isChecked());

       builder.setRequiresCharging(mRequiresChargingCheckBox.isChecked());

       PersistableBundle extras = new PersistableBundle();

       extras.putLong(WORK_DURATION_KEY,Long.valueOf(workDuration) * 1000);

       builder.setExtras(extras);

     JobSchedulertm = (JobScheduler)getSystemService(Context.JOB_SCHEDULER_SERVICE);

       tm.schedule(builder.build());

   }

 

publicclassMyJobServiceextends JobService {

    

       private ComponentNamemServiceComponent;

     @Override

       publicboolean onStartJob(final JobParameters params) {

       longduration =params.getExtras().getLong(WORK_DURATION_KEY);

   

           Handler handler = new Handler();

           handler.post(new Runnable() {

               @Override

               publicvoid run() {

                Log.i(TAG,"on start job: "+ params.getJobId()+"时间");

               

                jobFinished(params,true);

 

               }

           })

           // Return true as there's more workto be done with this job.

           returnfalse;

       }

       publicboolean onStopJob(JobParameters params) {

           returnfalse;

       }

   

 

我所做的需求是关于ota(系统更新)自动检测版本在androidn上收不到网络发生变化的广播,所以用jobservice解决问题。

思路是在重启广播中注册一个job,这个job采用线性增长的等待时间方式,且在有网的情况的下才会触发。由于需要不停的检测,但是因为job是一次性的,所以在myjobservice中的onstartjob中去启动处理ota自动版本检测的那个广播类,然后用了jobfinishparams,true)去告诉系统任务需要一直重试,这样系统就会不断地进行重试,并且有时间间隔的重试。满足了我们基本的网络监听需求。

 遇到了一个很奇怪的问题时在注册了jobinfo后,把ota的数据清楚了以后,会造成jobinfo死掉,所以我只好采用了用户再进入ota主界面后,会在启动一个Jobinfo,就是在mainactivity中判断是否被清除了数据,清楚了数据就在启动一个jobinfo,在这之前要把其他的都cancelall()掉,让系统只有一个jobinfo。判断是否清除了数据只要在sp中设置一个值,默认为false,进入重启广播就设为true,如果清除了数据,这个值就是false,没有清除就是true,等到下次进入到重新创建jobinfo的逻辑中,证明了它是fasle我们就把它再设为true.

 

具体的代码实现,就不能写了。

 

0 0
原创粉丝点击