当前位置: 首页 > 工具软件 > JobScheduler > 使用案例 >

Android Jobscheduler

符佐
2023-12-01

参考:JobScheduler的使用

1 简介

JobScheduler(作业调度器) 是Android L提供的API,可以通过内置的某些条件在满足条件的情况下执行特定的任务,Google采用了Job的方式,每个需要后台处理的业务为一个Job,通过管理系统Job来提高资源利用率,从而提高性能,节省电源。

使用 JobScheduler 可以替代传统的 WakeLockAlarm 运行app任务,可以将它看作“互相协作的WakeLock/Alarm”API。

每个app中的 WakeLockAlarm 都是相互独立的,但是 JobScheduler 将设备的唤醒抽离至操作系统层面。因为 AlarmWakeLock 受沙箱限制,所以无法与安装在设备上的其他应用相互协调。比如,设备上5个app每30分钟唤醒设备依次,则它们的唤醒几乎不可能同步,最终设备每小时会被唤醒10次。但由于 JobScheduler 是在系统层级,系统可以更有效地执行所有的调度工作,每小时唤醒设备的次数也会减少。

除了调度设备唤醒,JobScheduler 还允许设定获取数据的时间间隔,比如把唤醒时间限制在8分钟之后10分钟之内,这给操作系统留出一定的调整范围,让系统可以更好地协调唤醒以达到省电的目的。

JobScheduler支持的内置条件处理:

  • 网络:指定在哪种网络状态下启动Job

  • 电源:指定电源是否连接、电源大小情况启动Job

  • 设备:指定设备是否处于空闲状态启动Job

  • 存储:指定存储大小情况启动Job

2 JobScheduler API

JobScheduler关联三个API:

  • JobService:被JobScheduler启动的执行Job的服务

  • JobInfo:Job所需满足的条件和参数

  • JobScheduler:系统服务,用于启动指定的JobService

2.1 JobService

JobService 继承于Service,因此JobService同样是在主线程运行,如果需要执行耗时操作,需要放在子线程处理。

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

	/**
	 * 启动工作
	 * 
	 * @return 
     *
	 * 如果返回true,代表执行的将会是一个耗时任务,工作将会在异步执行,在执行完Job后要手动调用jobFinished()结束Job,否则系统不会再入队其他Job执行,即JobScheduler的执行队列阻塞
	 * 
	 * 如果返回false,代表处理的Job不是一个耗时任务
	 */
	@Override
	public boolean onStartJob(JobParamters params) {
		return false;
	}

	/**
	 * 结束工作
	 *
	 * 系统收到取消Job请求且这个Job仍然在执行,系统就会调用该方法,即onStartJob()要返回true且执行耗时的Job没有结束时会调用,否则不调用
	 */
	@Override
	public boolean onStopJob(JobParamters params) {
		return false;
	}
}

注册JobService:

<service android:name=".JobSchedulerService"
	android:permission="android.permission.BIND_JOB_SERVICE" />

2.2 JobInfo

JobInfo 是构建满足特定条件的Job执行参数信息。

private static final int JOB_ID = 1;

// JobSchedulerService是自定义的启动Job执行的服务
JobInfo.Builder jb = new JobInfo.Builder(JOB_ID, new ComponentName(getPackageName(), JobSchedulerService.class.getName()));

// 指定Job多少毫秒之后执行,与setPeriodic()互斥,同时使用会抛出异常
jb.setMinimumLatency(5000);

// 指定Job在多少毫秒之后执行无论条件是否满足,与setPeriodic()互斥
jb.setOverrideDeadline(10 * 1000);

// 是否系统重启后继续该Job执行,清单文件要添加权限android.permission.RECEIVE_BOOT_COMPLETED
jb.setPersisted(true);

// 指定Job每多少毫秒执行一次
jb.setPeriodic(3000);

// 指定启动Job时的网络类型
// JobInfo.NETWORK_TYPE_NONE:启动Job时不需要任何网络连接
// JobInfo.NETWORK_TYPE_ANY:启动Job时只要有网络就可以
// JobInfo.NETWORK_TYPE_NETWORK_TYPE_UNMETERED:启动Job时要连接wifi  
jb.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);

// 指定启动Job时是否需要连接电源
jb.setRequiresCharging(false);

// 指定启动Job时是否需要设别处于空闲状态
jb.setRequiresDeviceIdle(false);

// setRequiredNetworkType()、setRequiresCharging()、setRequiresDeviceIdle()同时使用时可能导致Job永远不会执行
// 这时需要设置setOverrideDeadline()确保Job在不满足条件时能被执行一次

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
	// 指定启动Job时是否为低电源
    jb.setRequiresBatteryNotLow(false);

    // 指定启动Job时是否为低存储
    jb.setRequiresStorageNotLow(false);
}

JobInfo jobInfo = jb.build();

2.3 JobScheduler

JobScheduler 是启动、取消任务的系统服务。

JobScheduler jobScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);

// 如果启动成功将返回1,否则返回0
int result = jobScheduler.schedule(jobInfo);
if (result <= 0) {
	// 取消Job
	jobScheduler.cancel(JOB_ID);
	jobScheduler.cancelAll();

	// 获取Job
	if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
		JobInfo pendingJob = jobScheduler.getPendingJob(JOB_ID);
	}
	List<JobInfo> allPendingJob = jobScheduler.getAllPendingJobs();
}

3 JobScheduler使用场景

我们使用 JobScheduler 主要是为了提高资源利用率从而达到省电的目的。

JobScheduler 主要处理的场景是:

  • 在系统层级调度唤醒设备,避免设备中多个app不同步各自频繁唤醒设备

  • 设定时间间隔获取数据

其他功能场景:

  • 运行一个周期服务,维持网络连接

  • 仅在不限流量的网络下运行某项工作(一般指wifi)

  • 仅在设备空闲时运行(API中对空闲状态说得不是很明确,只是说设备“有时候”会处于空闲状态)

  • 当设备接通电源时运行

  • 连接频率衰减;延长后续连接的间隔时间

 类似资料:

相关阅读

相关文章

相关问答