JobScheduler机制(一)

Android P

在android p 上, google 提出了应用待机分组, 分析其代码,涉及到了JobScheduler, 对其实习想学习一下, 故有JobScheduler机制 系列.

1 JobScheduler 使用

为了学习JobScheduler机制,首先要了解JobScheduler的使用,本节就简单的介绍JobScheduler的使用. 提供一个简单使用的demo : JobScheduler demo 仅供参考.

JobScheduler 程序首先要继承JobService对象, 并必须实现其中的两个抽象方法 onStartJobonStopJob:

  1. public class MyJobService extends JobService {
  2. private static final String TAG = "MyJobService";
  3. /**
  4. * false: 该系统假设任何任务运行不需要很长时间并且到方法返回时已经完成。
  5. * true: 该系统假设任务是需要一些时间并且当任务完成时需要调用jobFinished()告知系统。
  6. */
  7. @Override
  8. public boolean onStartJob(JobParameters params) {
  9. Log.i(TAG, "Totally and completely working on job " + params.getJobId());
  10. Log.d(TAG,"onStartJob");
  11. return true;
  12. }
  13. /**
  14. * 当收到取消请求时,该方法是系统用来取消挂起的任务的。
  15. * 如果onStartJob()返回false,则系统会假设没有当前运行的任务,故不会调用该方法。
  16. */
  17. @Override
  18. public boolean onStopJob(JobParameters params) {
  19. Log.i(TAG, "stop job " + params.getJobId());
  20. return false;
  21. }
  22. }

定义 Job ,并调用JobScheduler的schedule方法去执行:

  1. jobService = new ComponentName(this, MyJobService.class);
  2. Intent service = new Intent(this, MyJobService.class);
  3. startService(service);
  4. JobScheduler scheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
  5. JobInfo jobInfo = new JobInfo.Builder(10087, jobService) //任务Id等于123
  6. .setMinimumLatency(12345)// 任务最少延迟时间
  7. .setOverrideDeadline(60000)// 任务deadline,当到期没达到指定条件也会开始执行
  8. .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)// 网络条件,默认值NETWORK_TYPE_NONE
  9. .setRequiresCharging(true)// 是否充电
  10. .setRequiresDeviceIdle(false)// 设备是否空闲
  11. .setPersisted(true) //设备重启后是否继续执行 需要权限android.permission.RECEIVE_BOOT_COMPLETED
  12. .setBackoffCriteria(3000,JobInfo.BACKOFF_POLICY_LINEAR) //设置退避/重试策略
  13. .build(); // build 才是真正的执行创建
  14. Log.d(TAG,"scheduler.schedule");
  15. scheduler.schedule(jobInfo);

为了绑定JobService , 在AndroidManifest.xml中要添加service,并且定义权限android.permission.BIND_JOB_SERVICE

  1. <service android:name=".MyJobService"
  2. android:permission="android.permission.BIND_JOB_SERVICE"
  3. android:exported="true"/>

这里梳理一下流程:

  • 通过getSystemService获取JobSchedulerService的代理端
  • new Intent(this, MyJobService.class) 创建服务, 启动服务
  • 采用builder模式创建JobInfo对象
  • 调用JobScheduler.schedule(JobInfo) 启动JobInfo

2 查看定义的jobscheduler

当app设置的jobscheduler 之后,使用adb shell dumpsys jobscheduler 可以查看注册的jobscheduler, dumpsys 命令不需要使用root命令 :

  1. ......
  2. JOB #u0a174/10087: 86d97f7 com.lq.tct.tctapplication/.MyJobService
  3. u0a174 tag=*job*/com.lq.tct.tctapplication/.MyJobService
  4. Source: uid=u0a174 user=0 pkg=com.lq.tct.tctapplication
  5. JobInfo:
  6. Service: com.lq.tct.tctapplication/.MyJobService
  7. PERSISTED
  8. Requires: charging=true batteryNotLow=false deviceIdle=false
  9. Network type: 2
  10. Minimum latency: +12s345ms
  11. Max execution delay: +1m0s0ms
  12. Backoff: policy=0 initial=+10s0ms
  13. Has early constraint
  14. Has late constraint
  15. Required constraints: CHARGING TIMING_DELAY DEADLINE UNMETERED
  16. Satisfied constraints: CHARGING BATTERY_NOT_LOW APP_NOT_IDLE DEVICE_NOT_DOZING
  17. Unsatisfied constraints: TIMING_DELAY DEADLINE UNMETERED
  18. Tracking: BATTERY CONNECTIVITY TIME
  19. Enqueue time: -1s976ms
  20. Run time: earliest=+10s369ms, latest=+58s24ms
  21. Ready: false (job=false user=true !pending=true !active=true !backingup=true comp=true)
  22. ......

如果能获取root权限, 还可以查看/data/system/job/jobs.xml 文件:

  1. <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
  2. <job-info version="0">
  3. <job jobid="10087" package="com.lq.tct.tctapplication" class="com.lq.tct.tctapplication.MyJobService" sourcePackageName="com.lq.tct.tctapplication" sourceUserId="0" uid="10174" priority="0" flags="0" lastSuccessfulRunTime="0" lastFailedRunTime="0">
  4. <constraints unmetered="true" charging="true" />
  5. <one-off deadline="1264103317926" delay="1264103270271" backoff-policy="0" initial-backoff="10000" />
  6. <extras />
  7. </job>
  8. <job jobid="1" package="com.tencent.mobileqq" class="com.tencent.mobileqq.msf.service.MSFAliveJobService" sourcePackageName="com.tencent.mobileqq" sourceUserId="0" uid="10163" priority="0" flags="0" lastSuccessfulRunTime="1262980997656" lastFailedRunTime="0">
  9. <constraints />
  10. <periodic period="900000" flex="900000" deadline="1262982797615" delay="1262981897615" />
  11. <extras />
  12. </job>
  13. .....
  14. </job-info>

两种查看jobscheduler方式,结果形式比一样,但是显示的内容都是相同的,eg : jobid: 10087是我们在前面的代码中定义的. 对于在定义job的时候的详细的参数,都在dumpsys或者job.xml中查看到.constraints 就是对应的限制条件,可参考: Android省电的秘密(2)之adb解读JobScheduler

参看Blog