文章目录

  • 一、JobScheduler 提交任务 schedule 方法源码分析
  • 二、schedule(JobInfo job, int uId) 方法
  • 三、scheduleAsPackage 方法
  • 四、startTrackingJob 方法
  • 五、JobSchedulerService 源码注释

上一篇博客 【Android 电量优化】电量优化 ( JobScheduler | JobService | AsyncTask ) 中使用了 JobScheduler 进行电量优化 , 将消耗电量的操作 , 都在设定的条件下集中执行 , 达到减少唤醒硬件的频率 , 省电的目的 ; 本篇博客中从源码角度分析上述操作的底层原理 ;

推荐代码查看网站 :

  • https://www.androidos.net.cn/sourcecode ( 推荐 )

  • http://androidxref.com/

一、JobScheduler 提交任务 schedule 方法源码分析


JobScheduler 的功能依赖 JobSchedulerService 系统服务完成 ;

使用 JobScheduler 对象提交任务的方法 schedule(jobInfo) , 最终跨进程调用的 JobSchedulerService 中的 int schedule(JobInfo job, int uId) 方法 ;

二、schedule(JobInfo job, int uId) 方法


JobSchedulerService 中的 int schedule(JobInfo job, int uId) 方法解析 :

JobScheduler 的提交任务方法 schedule , 最终调用到 int schedule(JobInfo job, int uId) 方法 , 该调用是跨进程调用的 ;

int schedule(JobInfo job, int uId) 方法 是客户端的 JobScheduler 调用 schedule 方法执行后的入口函数 , 提供一个 JobInfo job 任务 ; 如果任务已经被安排 , 那么取消该任务 , 并使用新传入的该 JobInfo job 参数代替原来的任务 ;

三、scheduleAsPackage 方法


在 int schedule(JobInfo job, int uId) 方法中 , 实际调用了 int scheduleAsPackage(JobInfo job, int uId, String packageName, int userId, String tag) 方法 ,

参数说明 :

  • job 任务信息
  • uId 任务 id
  • packageName 包名
  • userId 用户 id ;

在上述 scheduleAsPackage 方法中 , 进行了一系列的状态判定 , 如包名不能为空 , 当前任务数量没有超过最大值 MAX_JOBS_PER_APP , 如果上述判定通过 , 就调用 void startTrackingJob(JobStatus jobStatus, JobStatus lastJob) 方法 , 该方法用于追踪任务状态 ;

四、startTrackingJob 方法


当我们有一个任务状态对象 , 我们需要插入到 JobStore 时 , 回调 void startTrackingJob(JobStatus jobStatus, JobStatus lastJob) 方法 , 确保所有相关的控制器知道该状态 ;

以下控制器需要知道任务状态 :

  • ConnectivityController
  • TimeController
  • IdleController
  • BatteryController
  • AppIdleController
  • ContentObserverController
  • DeviceIdleJobsController

这些控制器都封装在 List mControllers 成员变量中 , 该集合是 JobSchedulerService 的成员变量 ;

上述控制器在 public JobSchedulerService(Context context) 构造函数中初始化并放入 mControllers 集合中 ;

五、JobSchedulerService 源码注释


public class JobSchedulerService extends com.android.server.SystemServiceimplements StateChangedListener, JobCompletedListener {/** 任务的主要集合. */final JobStore mJobs;/** 控制器集合 , 提醒该 Service 服务区更新任务. */List<StateController> mControllers;/*** 初始化系统服务* <p>* 子类必须定义一个单参数的构造函数 , 接收 Context context 参数 , 并且传递给父类* </p>** @param context 系统服务上下文对象*/public JobSchedulerService(Context context) {super(context);mHandler = new JobHandler(context.getMainLooper());mConstants = new Constants(mHandler);mJobSchedulerStub = new JobSchedulerStub();mJobs = JobStore.initAndGet(this);// 创建控制器集合// 后续会遍历该集合 , 遍历出的元素会调用 maybeStartTrackingJobLocked 方法mControllers = new ArrayList<StateController>();// 网络控制器mControllers.add(ConnectivityController.get(this));mControllers.add(TimeController.get(this));mControllers.add(IdleController.get(this));// 电量控制器mControllers.add(BatteryController.get(this));mControllers.add(AppIdleController.get(this));mControllers.add(ContentObserverController.get(this));mControllers.add(DeviceIdleJobsController.get(this));}// JobScheduler 的提交任务方法 schedule , 最终调用到该方法// 跨进程方式调用 // 这是客户端的 JobScheduler 调用 schedule 方法执行后的入口函数 , 提供一个 JobInfo job 任务 ; // 如果任务已经被安排 , 那么取消该任务 , 并使用新传入的该 JobInfo job 参数代替原来的任务 ; public int schedule(JobInfo job, int uId) {return scheduleAsPackage(job, uId, null, -1, null);}// 实际调用的方法 , 传入 JobInfo job 任务信息 , uId 任务 id , packageName 包名 , userId 用户 id , public int scheduleAsPackage(JobInfo job, int uId, String packageName, int userId,String tag) {// 创建任务状态JobStatus jobStatus = JobStatus.createFromJobInfo(job, uId, packageName, userId, tag);// ... 省略       JobStatus toCancel;synchronized (mLock) {// 判定状态是否合法 , 包名不能为空 , 当前任务数量没有超过最大值 MAX_JOBS_PER_APPif (ENFORCE_MAX_JOBS && packageName == null) {if (mJobs.countJobsForUid(uId) > MAX_JOBS_PER_APP) {Slog.w(TAG, "Too many jobs for uid " + uId);// 如果多于最大任务数 , 就要抛出异常 throw new IllegalStateException("Apps may not schedule more than "+ MAX_JOBS_PER_APP + " distinct jobs");}}toCancel = mJobs.getJobByUidAndJobId(uId, job.getId());if (toCancel != null) {cancelJobImpl(toCancel, jobStatus);}// 如果上述判定通过 , 就调用该方法 , 该方法用于追踪任务状态 startTrackingJob(jobStatus, toCancel);}mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();return JobScheduler.RESULT_SUCCESS;}/*** 当我们有一个任务状态对象 , 我们需要插入到 JobStore 时 , 回调该方法 , * 确保所有相关的控制器知道它 ;*/private void startTrackingJob(JobStatus jobStatus, JobStatus lastJob) {synchronized (mLock) {// 将本次调度的任务加入到 JobStore mJobs 集合中final boolean update = mJobs.add(jobStatus);if (mReadyToRock) {// 遍历控制器集合 List<StateController> mControllersfor (int i = 0; i < mControllers.size(); i++) {StateController controller = mControllers.get(i);if (update) {controller.maybeStopTrackingJobLocked(jobStatus, null, true);}// 调用控制器的 maybeStartTrackingJobLocked 函数 controller.maybeStartTrackingJobLocked(jobStatus, lastJob);}}}}
}

该代码路径为 /frameworks/base/services/core/java/com/android/server/job/JobSchedulerService.java , 点击链接可跳转查看完整源码 ;

【Android 电量优化】JobScheduler 相关源码分析 ( JobSchedulerService 源码分析 | Android 源码在线网址推荐 )相关推荐

  1. 【Android 电量优化】JobScheduler 源码分析 ( JobServiceContext 源码分析 | 闭环操作总结 | 用户提交任务 | 广播接收者接受相关广播触发任务执行 )★

    文章目录 一.JobServiceContext 引入 二.JobServiceContext 源码分析 三.用户在应用层如何使用 JobScheduler 四.用户提交任务 五.广播接收者监听广播触 ...

  2. 【Android 电量优化】JobScheduler 相关源码分析 ( JobSchedulerService 源码分析 | 任务检查 | 任务执行 )

    文章目录 一.回调 StateChangedListener 接口 二.JobHandler 处理 ( 任务检查 ) 三.maybeRunPendingJobsH 方法 四.assignJobsToC ...

  3. 【Android 电量优化】JobScheduler 相关源码分析 ( ConnectivityController 底层源码分析 | 构造函数 | 追踪任务更新 | 注册接收者监听连接变化 )

    文章目录 一.ConnectivityController 连接控制器引入 二.ConnectivityController 构造方法解析 ( 注册接收者 ) 三.mConnectivityRecei ...

  4. 【Android 电量优化】电量优化 ( Battery Historian 环境要求 | 电量分析报告 | 电量优化三原则 | 电量优化注意事项 )

    文章目录 一.Battery Historian 环境要求 二.上传电量报告 三.Battery Historian 电量分析报告 四.电量优化三原则 五.电量优化注意事项 参考 Google 官方文 ...

  5. 【Android 电量优化】电量优化 ( 获取电量分析报告 | 阿里云服务器搭建 Battery Historian | 上传并生成分析报告 )

    文章目录 一.Battery Historian 搭建环境 二.获取 Android 手机电量报告 1.重置电量状态 2.开启获取 WeakLock 信息 3.获取手机电量报告 三.阿里云服务器搭建 ...

  6. 【Android 电量优化】电量优化 ( 使用 AlarmManager 保持 CPU 唤醒 )

    文章目录 一.AlarmManager 简介 二.使用 AlarmManager 保持 CPU 唤醒流程 ( 省电操作 ) 三.使用 WeakLock 保持 CPU 唤醒 代码示例 1.Service ...

  7. 【Android 电量优化】电量优化 ( JobScheduler | JobService | AsyncTask )

    文章目录 一.JobScheduler 使用流程 二.AsyncTask 简介 三.JobScheduler 开发流程 四.JobScheduler 代码示例 1.JobScheduleManager ...

  8. Android电量优化

    最近领导老是反映说我们的APP耗电要比以前厉害一些,排在耗电量的首位,上黑名单了,需要进行电量优化!经过一段时间的研究,自己做了一部分的总结! 电量优化的工具battery-historien bat ...

  9. 详解Android电量优化

    目录 写在前面 一.电量优化介绍及方案选择 1.1.如何正确认识电量优化 1.2.耗电量测试方案 二.Battery Historian实战分析 三.电量辅助监控实战 3.1.获取运行时能耗 3.2. ...

最新文章

  1. 435. 无重叠区间(贪心算法)
  2. 12个python超强学习网站!加python书籍推荐!( 入门python自学推荐!建议收藏!)
  3. Xamarin Essentials教程检查网络连通性Connectivity
  4. 优图yolo-v2 loss解析(tensorflow)
  5. 开运算和闭运算_OpenCV计算机视觉学习(5)——形态学处理(腐蚀膨胀,开闭运算,礼帽黑帽,边缘检测)...
  6. (技能篇)Mysql在linux下的全量热备份
  7. 【华为大咖分享】1.云上开发,代码托管只是第一步(后附PPT下载地址)
  8. [VMM 2008虚拟化之初体验-1] 准备环境
  9. Oracle性能调优
  10. devops handbook 读书笔记_DevOps教程:DevOps 面试题
  11. windows录屏_Windows电脑录屏制作gif神器
  12. 从IOE看云行业的潜力
  13. DevOps企业实践指南(1):DevOps能为我们带来什么
  14. python通用管理系统_Python实例---CRM管理系统分析180331
  15. 上市公司杰创智能携手甄云,启动供应链采购数字化升级
  16. Mac上安装虚拟机搭载window系统
  17. 科技爱好者周刊(第 141 期):封闭系统的胜利
  18. 记账之后的收支明细,如何以收支图表的形式呈现
  19. matlab赋值一行,matlab – 0和1的矩阵,其中后续行中的赋值取决于前一行
  20. 中南大学杰出校友_杰出客户服务的10个要点。

热门文章

  1. java BlockingQueue 用法
  2. Cookie,Session
  3. JZOJ5922. 【NOIP2018模拟10.23】sequence
  4. ESP系列AT指令开发笔记
  5. CentOS安装Navicat
  6. 基本概念之运算符与表达式
  7. BZOJ 2303 方格染色(带权并查集)
  8. nmake构建Geos库
  9. JAVA防盗链在报表中的应用实例
  10. 如何注册iClap账号?