JobScheduler 实现 特定时间,特定条件(系统空闲,电池电量,磁盘空间 ……)下执行任务

JobScheduler 简介

使用场景

  • 应用保活
  • 特定时间,特定条件(系统空闲,电池电量,磁盘空间 ……)下运行程序

JobScheduler 提供分发各种条件的任务(通过 JobInfo构建),这个任务由系统在满足你设置的条件下执行(执行是通过调用JobService)。系统在执行任务时会批量和尽可能的延迟执行,如不设置deadline 的话,这个任务可能在任何延后的时刻执行。任务执行时你的app持有wakelock锁,保证任务能执行下去不会休眠
note:
从API 30 (Build.VERSION_CODES.R)10.0+开始,JobScheduler 的schedule调用会导致app bug,并且这个无视
target SDK version;也就是API 30不能再使用JobScheduler

分发
满足 JobInfo设置的条件
JobScheduler
JobInfo
执行JobService

JobScheduler 对象获取

JobScheduler是在Android 5.0中才有的

//JobScheduler系统服务获取
JobScheduler jobScheduler = (JobScheduler) getSystemService( Context.JOB_SCHEDULER_SERVICE );

JobInfo构建

ComponentName serviceName = new ComponentName("yourPackageName",
       "^.MyJobService");
JobInfo jobInfo = new JobInfo.Builder(JOB_ID, serviceName)
       //.setMinimumLatency(3000)
       .setPeriodic(15 * 60 * 1000)
       .build();

JobInfo提供的方法参数解释

方法说明
public Builder(int jobId, @NonNull ComponentName jobService)Builder构建构造函数;jobId:区别不同JobInfo ;ComponentName :指定满足条件后执行的jobService包名和类名
以下是设置时间相关条件
setMinimumLatency(long minLatencyMillis)设置任务执行的最小延迟时间,也就是minLatencyMillis时间之后执行,可能无限之后,需要配合setOverrideDeadline使用;不能和periodic job一起使用,会在build()的时候抛出参数异常
setOverrideDeadline(long maxExecutionDelayMillis)设置任务执行的最大延迟时间,可以与setMinimumLatency配合使用,这样就是在一个时间区间内执行
setPeriodic(long intervalMillis, long flexMillis)设置任务在一个时间周期重复执行,并且有一个弹性时间;执行序列start–>[flex,period]–>[flex,period]…… ;参数要求:intervalMillis要>getMinPeriodMillis(),否则就使用系统默认的getMinPeriodMillis()=15 minutes;flexMillis 要大于A=max(getMinFlexMillis()=5 minutes ,intervalMillis * 5%) ,否则就使用A
setPeriodic(long intervalMillis)直接调用setPeriodic(intervalMillis, intervalMillis)
以下是设置机器状态的相关条件
setRequiredNetworkType(@NetworkType int networkType)设置需要的网络状况
setRequiresCharging(boolean requiresCharging)设置是否需要设备插电中,默认false
setRequiresBatteryNotLow(boolean batteryNotLow)设置是否在电池非低状态
setRequiresDeviceIdle(boolean requiresDeviceIdle)设置是否在设备空闲状态
setRequiresStorageNotLow(boolean storageNotLow)设置是否在磁盘非低状态
设置完条件后,需要执行得到JobInfo 对象
public JobInfo build()构建出JobInfo 对象,采用了Builder设计模式

JobService 定义

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

}

需要在AndroidManifest.xml中注册

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

JobScheduler通过JobInfo调用JobService

       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            JobScheduler scheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
            JobInfo.Builder builder = new JobInfo.Builder(1, new ComponentName(context.getPackageName(), MyJobService.class.getName()));
            /**
             * 5分钟后执行,可能一直延后
             * 这个设置不能和周期性任务一起设置
             */
            builder.setMinimumLatency(5 * 60 * 1000);
            /**
             * 截止到20分钟之前执行;设置了这个Deadline,requirements相关条件不满足也会执行
             * 这个设置不能和周期性任务一起设置
             */
            builder.setOverrideDeadline(20 * 60 * 1000);

            /**
             * 设置需要的网络条件
             * 
             * 如果设置了这个requirements又设置了setOverrideDeadline可以通过
             * JobService中的onStartJob(JobParameters params)中的isOverrideDeadlineExpired()判断是不是由Deadline触发
             */
            builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
            
            JobInfo jobInfo = builder.build();
            scheduler.schedule(jobInfo);
        }

版本对JobScheduler 的影响

谷歌开发文档:

Note: Beginning with API 30 (Build.VERSION_CODES.R), JobScheduler will throttle runaway applications. Calling schedule(android.app.job.JobInfo) and other such methods with very high frequency is indicative of an app bug and so, to make sure the system doesn’t get overwhelmed, JobScheduler will begin to throttle apps that show buggy behavior, regardless of target SDK version.

API 30开始JobScheduler 将会报错,哪怕你把target SDK 调低也没用


此文要是对你有帮助,如果方便麻烦点个赞,谢谢!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Foreground Service + JobScheduler 的方式可以通过同时利用前台服务和 JobScheduler实现应用保活,可以在系统资源充足的情况下执行任务,同时不会在通知栏显示持续的通知。下面是一个简单的实现方式: 1. 创建一个前台服务,将应用置于前台状态,并在 onStartCommand() 方法中返回 START_STICKY,表示服务被杀掉后会被系统重启。 ``` public class ForegroundService extends Service { ... @Override public int onStartCommand(Intent intent, int flags, int startId) { startForeground(NOTIFICATION_ID, new Notification()); return START_STICKY; } ... } ``` 2. 在 onCreate() 方法中创建一个 JobScheduler,定时执行任务。 ``` public class ForegroundService extends Service { ... private JobScheduler mJobScheduler; ... @Override public void onCreate() { super.onCreate(); mJobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); JobInfo jobInfo = new JobInfo.Builder(JOB_ID, new ComponentName(this, JobSchedulerService.class)) .setPeriodic(15 * 60 * 1000) // 每 15 分钟执行一次任务 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .build(); mJobScheduler.schedule(jobInfo); } ... } ``` 3. 创建一个 JobService,在 onStartJob() 方法中执行需要保持应用活跃的操作。 ``` public class JobSchedulerService extends JobService { ... @Override public boolean onStartJob(JobParameters params) { // 执行需要保持应用活跃的操作 return true; } ... } ``` 需要注意的是,为了避免被系统误识别为滥用权限,任务执行间隔不宜过于频繁,同时需要适当调整任务的优先级和网络条件等参数,以确保任务可以在系统资源充足的情况下执行

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值