Android项目笔记:JobService

在Android5.0之后,系统为我们提供了一个后台定时任务,在特定的条件下触发。它就是JobService。
JobService在满足条件的情况下,会在APP的主线程中执行任务。因此需要我们注意不能直接执行耗时的任务。

JobService的使用首先要先申请一个保护权限 "android.permission.BIND_JOB_SERVICE" ,否则系统将跳过这个JobService。
<service android:name="MyJobService"
              android:permission="android.permission.BIND_JOB_SERVICE" >

JobService 继承自 Service,使用上也相对简单,涉及到的主要方法有以下几个:

 public class JobSchedulerService extends JobService {
    @Override
    public boolean onStartJob(JobParameters params) {

        return false;
    }

    @Override
    public boolean onStopJob(JobParameters params) {

        return false;
    }

 }

boolean onStartJob(JobParameters params) 

    第一个需要重写的方法,该方法在Job满足条件时,开始被调用。我们需要在该方法中实现我们自己的需求逻辑。需要特别注意的是,这个方法是执行在应用的主线程里面的,所以要避免直接使用耗时操作。
该方法返回一个布尔值,返回true表示该job需要继续运行,如果我们选择返回true,job会一直处于存活状态直到我们手动调用JobFinished告诉系统任务完成了或者job设定的条件不再满足了。比如:我们的jobschedule设定了setRequiresCharging(true),那么当我们不再充电的时候,该job就会被立即停止。这个时候 onStopJob(JobParameters)就会被调用。如果返回的是false,则表示该job在return的时候已经结束,并且onStopJob(JobParameters) 不会被调用。

    该方法传入一个JobParameters参数,该参数表示Job的配置信息,用于标识正在运行中的job,比如在调用jobFinished(JobParameters, boolean)时传入。


boolean onStopJob (JobParameters params)

    该方法会在系统决定停止该job时调用,不管你是否调用了jobFinished。
    该方法传入JobParameters ,这个与onStartJob中的相同。该方法返回一个布尔值,返回true用来告诉JobManager你是否要重试该job,重试的条件在创建job的时候定义。返回false的话表示该job将完全结束。不管我们选择返回什么值,这一次的job将必定会被停止执行。


void jobFinished (JobParameters params, boolean wantsReschedule)

    调用该方法用来手动停止某一个job,我们可以通过传入true给wantsReschedule来表示希望重新计划该job。我们可以通过setBackoffCriteria 来调整重试的策略。这里不展开。


看完JobService的主要方法,接下来看看如何构建并配置任务:

首先获取到schedule:

JobScheduler js = context.getSystemService(JobScheduler.class);

接下来我们使用builder模式创建一个JobInfo,设置相应的属性和配置项,这些配置项决定了Job什么时候会被触发。

JobInfo jobInfo = new JobInfo.Builder(OOBEConstant.JB_ID_SUPPORT_CHECK, new ComponentName(context.getPackageName(), OOBEQueryIfSupportJobService.class.getName()))
        .setPersisted(true)
        .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
        .build();

完成配置之后我们就可以安排执行任务了:

js.schedule(jobInfo);

可以看到为了满足我们的条件,关键还是在构建JobInfo的时候设置符合我们要求的属性,这里我贴上一些常用的:

addTriggerContentUri(JobInfo.TriggerContentUri uri)
添加监听一个Uri,如果发生改变就会触发job

setBackoffCriteria(long initialBackoffMillis, int backoffPolicy)
设置重试策略

setMinimumLatency(long minLatencyMillis)
设置job延迟的最短时间

setPersisted(boolean isPersisted)
设置重启后是否生效

setRequiredNetworkType(int networkType)
设置job需要的网络类型

JobScheduler 用于整体的调度,它主要涉及以下几个方法:

schedule(JobInfo job)
安排执行一个job,它会返回一个int值,RESULT_SUCCESS表示成功安排,RESULT_FAILURE表示失败。

cancel(int jobId)
取消一个特定的job

cancelAll()
取消由该应用所有已经计划的job

值得注意的是,当job在运行的时候,系统会给APP一个wakelock,也就是它保证了我们的job在运行的时候设备会一直处于唤醒的状态。

下面贴主要代码:

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class ShowNotificationJobService extends JobService {

    @Override
    public boolean onStartJob(JobParameters params) {
        Intent intent = new Intent(START_NOTIFICATION);
        intent.setClass(this, FlowController.class);
        sendBroadcast(intent);
        return false;
    }

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

    public static void schedule(Context context){

        long startupTime = Utils.getPreferences(context).getLong(Constant.SP_PARAM_TIME,0);
        long latency = Constant.NOTIFICATION_DELAY - (System.currentTimeMillis() - startupTime);
        JobScheduler js = (JobScheduler) context.getSystemService(JOB_SCHEDULER_SERVICE);
        JobInfo.Builder builder = new JobInfo.Builder(Constant.JB_ID_NOTIFICATION_CHECK, new ComponentName(context.getPackageName(), ShowNotificationJobService.class.getName()))
                .setPersisted(true)
                .setMinimumLatency(latency)
                .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
        if(latency > 0){
            builder.setMinimumLatency(latency);
        }

        js.schedule(builder.build());
        if( result == JobScheduler.RESULT_SUCCESS ){
		Log.i(TAG, "scheduled success");
	}
	else {
		Log.i(TAG, "scheduled failed");
	}

    }

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值