日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

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

發布時間:2025/6/17 Android 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Android 电量优化】JobScheduler 相关源码分析 ( JobSchedulerService 源码分析 | Android 源码在线网址推荐 ) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 一、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 源码在线网址推荐 )的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。