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

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

文章目录

一、JobServiceContext 引入

二、JobServiceContext 源码分析

三、用户在应用层如何使用 JobScheduler

四、用户提交任务

五、广播接收者监听广播触发 JobService 执行任务



推荐代码查看网站 :


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


http://androidxref.com/






一、JobServiceContext 引入


上一篇博客 【Android 电量优化】JobScheduler 相关源码分析 ( JobSchedulerService 源码分析 | 任务检查 | 任务执行 ) 中在 JobSchedulerService 中的 assignJobsToContextsLocked 方法中 , 有如下代码 :


// /frameworks/base/services/core/java/com/android/server/job/JobSchedulerService.java 中的代码
mActiveServices.get(i).executeRunnableJob(pendingJob)


mActiveServices 就是 JobServiceContext 集合 , 上述方法调用了 JobServiceContext 的 executeRunnableJob 方法 , 目的是要执行传入的 pendingJob 任务 ;






二、JobServiceContext 源码分析


在 JobServiceContext 类的 executeRunnableJob 方法的作用 : 该方法传递一个 Job 任务给 JobServiceContext 执行 , 调用者需要先检查如下两个条件 :


当前是否有运行中的任务 , getRunningJob() 必须为空 ;

同时还需要确保该 JobServiceContext 上下文是有效的 ;


在该方法中创建了 Intent , 并使用该意图绑定了一个服务 , 这个服务就是创建 JobInfo 时 , 开发者自定义的 JobService 服务 , 提交任务时需要提交该服务 ;


绑定服务 , 执行 JobService 服务中的 onStartJob 方法



截止到此处 , 基本 JobScheduler 整个运行的闭环 , 进行了简单的源码分析 , 没有深入分析 , 仅限于简单了解 ;


public class JobServiceContext extends IJobCallback.Stub implements ServiceConnection {
  // ... 
    /**
     * 该方法传递一个 Job 任务给 JobServiceContext 执行 . 
     * 调用者需要先检查当前是否有运行中的任务 , getRunningJob() 为空 ; 
     * 并且确保该 JobServiceContext 上下文是有效的 ; 
     * 
     * @param 将要运行的任务的状态 ;
     * @return True 如果该任务是有效的 , 并且正在执行 ; 
     *      False 如果该任务不能被执行 ; 
     */
    boolean executeRunnableJob(JobStatus job) {
        synchronized (mLock) {
            // ...
    // 此处创建了 Intent , 并使用该意图绑定了一个服务 
            final Intent intent = new Intent().setComponent(job.getServiceComponent());
            // 使用上述意图 Intent 绑定服务 
            // 这个服务就是创建 JobInfo 时 , 开发者自定义的 JobService 服务 , 提交任务时需要提交该服务  
            boolean binding = mContext.bindServiceAsUser(intent, this,
                    Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND,
                    new UserHandle(job.getUserId()));
            // ... 
            try {
              // 启动服务 , 会执行 JobService 服务中的 onStartJob 方法
                mBatteryStats.noteJobStart(job.getBatteryName(), job.getSourceUid());
            } catch (RemoteException e) {
                // Whatever.
            }
            mJobPackageTracker.noteActive(job);
            mAvailable = false;
            return true;
        }
    }
}



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






三、用户在应用层如何使用 JobScheduler


先讲解用户在应用层如何使用 JobScheduler :



在 【Android 电量优化】电量优化 ( JobScheduler | JobService | AsyncTask ) 博客中 , 讲解了 JobScheduler 如何使用 ;


获取服务 : 首先获取系统的 JobScheduler 服务 , 就是之前分析的 JobSchedulerService 类 ;

创建任务 : 创建 JobInfo 任务信息 , 使用 JobScheduler 提交该任务 ; mJobScheduler.schedule(jobInfo) ;

自定义 JobService : 开发者在应用中自定义 JobService 服务 ;

服务执行 : 系统会在合适的时间调用 JobService 服务的 boolean onStartJob(JobParameters params) 方法 ;


其中涉及到两个入口 , 一个是用户提交任务 , 另一个是系统在某个时间回调 JobService 服务中的开始执行任务方法 ;


主要针对上述两个入口进行分析 ;


用户提交任务的驱动事件是开发者写的提交任务的代码 ;


系统回调 JobService 服务的驱动事件 , 是用户对手机的操作 , 如插拔电源线 , 切换 WIFI 网络等操作 , 这些操作触发广播 , 相应广播接收者收到这些广播 , 就会触发一系列相关的操作 ;






四、用户提交任务


分析用户提交任务 :



【Android 电量优化】JobScheduler 相关源码分析 ( JobSchedulerService 源码分析 | Android 源码在线网址推荐 ) 博客中讲解了如下内容 :


JobScheduler 提交任务的方法 schedule(jobInfo) , 最终调用的是 JobSchedulerService 中的 schedule 方法 ;

在 schedule 方法中调用了 scheduleAsPackage 方法 , 传入任务相关信息 , 进行了一系列的状态判定 ;

在 scheduleAsPackage 方法中调用 startTrackingJob 方法 , 该方法中遍历所有的状态控制器 , 确保所有相关的控制器知道该状态 ;

【Android 电量优化】JobScheduler 相关源码分析 ( ConnectivityController 底层源码分析 | 构造函数 | 追踪任务更新 | 注册接收者监听连接变化 ) 博客中接着上面的博客继续分析 :


在 startTrackingJob() 方法中 , 调用状态控制器 StateController 的 maybeStartTrackingJobLocked 方法 , 该方法的作用是更新所有对应的状态控制器监听的任务 ;





五、广播接收者监听广播触发 JobService 执行任务


广播接收者监听广播 : 这是触发系统回调 JobService 服务的入口 ;



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


注册广播接收者 : ConnectivityController 中注册了广播接收者 , 用于监听 ConnectivityManager.CONNECTIVITY_ACTION 广播 , 这是网络状态改变后发出的广播 ;

广播接收者收到网络状态改变的广播后 , 会调用 updateTrackedJobs(-1) 方法 ;

该方法会更新所有对网络状态敏感的任务 , 例如有的任务要求在 WIFI 条件下执行 , 此时就会触发该任务的状态改变 ;

updateTrackedJobs 方法中又会调用 状态改变监听器 mStateChangedListener 的 onControllerStateChanged 方法 ;

状态改变监听器 mStateChangedListener 就是 JobSchedulerService 类 ;

【Android 电量优化】JobScheduler 相关源码分析 ( JobSchedulerService 源码分析 | 任务检查 | 任务执行 ) 博客中讲解后续操作 :


在实现的 StateChangedListener 接口的 onControllerStateChanged() 回调方法中 , 使用 JobHandler mHandler 发送了 MSG_CHECK_JOB 消息 ;

在 JobHandler 中接收上述消息 , 并检查任务 , 最终调用 maybeRunPendingJobsH() 方法 , 执行任务 ;

在 maybeRunPendingJobsH 方法中 , 调用 assignJobsToContextsLocked , 执行任务 ;

在 assignJobsToContextsLocked 方法中 , 最终调用了 JobServiceContext 执行 executeRunnableJob(pendingJob) 方法 , 用于执行 pendingJob 任务 ;

最终在 JobServiceContext 中绑定用户自定义的 JobService , 开始执行任务 , 会自动回调下面代码中的 onStartJob 方法 ;

public class BpJobService extends JobService {
    @Override
    public boolean onStartJob(JobParameters params) {
        // 启动 AsyncTask 异步任务处理工作
        new JobAsyncTask().execute(params);
        return false;
    }
    // ... 省略部分代码
}




本篇博客涉及到的源码 :


/frameworks/base/services/core/java/com/android/server/job/JobSchedulerService.java

frameworks/base/services/core/java/com/android/server/job/controllers/ConnectivityController.java

/frameworks/base/services/core/java/com/android/server/job/JobServiceContext.java


目录
相关文章
|
1月前
|
算法 Linux 调度
深入探索安卓系统的多任务处理机制
【10月更文挑战第21天】 本文旨在为读者提供一个关于Android系统多任务处理机制的全面解析。我们将从Android操作系统的核心架构出发,探讨其如何管理多个应用程序的同时运行,包括进程调度、内存管理和电量优化等方面。通过深入分析,本文揭示了Android在处理多任务时所面临的挑战以及它如何通过创新的解决方案来提高用户体验和设备性能。
45 1
|
4月前
|
移动开发 监控 前端开发
构建高效Android应用:从优化布局到提升性能
【7月更文挑战第60天】在移动开发领域,一个流畅且响应迅速的应用程序是用户留存的关键。针对Android平台,开发者面临的挑战包括多样化的设备兼容性和性能优化。本文将深入探讨如何通过改进布局设计、内存管理和多线程处理来构建高效的Android应用。我们将剖析布局优化的细节,并讨论最新的Android性能提升策略,以帮助开发者创建更快速、更流畅的用户体验。
72 10
|
1月前
|
Linux Android开发 iOS开发
深入探索Android与iOS的多任务处理机制
在移动操作系统领域,Android和iOS各有千秋,尤其在多任务处理上展现出不同的设计理念和技术实现。本文将深入剖析两大平台在后台管理、资源分配及用户体验方面的策略差异,揭示它们如何平衡性能与电池寿命,为用户带来流畅而高效的操作体验。通过对比分析,我们不仅能够更好地理解各自系统的工作机制,还能为开发者优化应用提供参考。
|
2月前
|
Android开发
Android gradle task任务检查各个module之间资源文件冲突.md
Android gradle task任务检查各个module之间资源文件冲突.md
Android gradle task任务检查各个module之间资源文件冲突.md
|
3月前
|
存储 缓存 编解码
Android经典面试题之图片Bitmap怎么做优化
本文介绍了图片相关的内存优化方法,包括分辨率适配、图片压缩与缓存。文中详细讲解了如何根据不同分辨率放置图片资源,避免图片拉伸变形;并通过示例代码展示了使用`BitmapFactory.Options`进行图片压缩的具体步骤。此外,还介绍了Glide等第三方库如何利用LRU算法实现高效图片缓存。
75 20
Android经典面试题之图片Bitmap怎么做优化
|
2月前
|
调度 Android开发 开发者
构建高效Android应用:探究Kotlin多线程优化策略
【10月更文挑战第11天】本文探讨了如何在Kotlin中实现高效的多线程方案,特别是在Android应用开发中。通过介绍Kotlin协程的基础知识、异步数据加载的实际案例,以及合理使用不同调度器的方法,帮助开发者提升应用性能和用户体验。
64 4
|
1月前
|
安全 Android开发 iOS开发
深入探索iOS与Android系统的差异性及优化策略
在当今数字化时代,移动操作系统的竞争尤为激烈,其中iOS和Android作为市场上的两大巨头,各自拥有庞大的用户基础和独特的技术特点。本文旨在通过对比分析iOS与Android的核心差异,探讨各自的优势与局限,并提出针对性的优化策略,以期为用户提供更优质的使用体验和为开发者提供有价值的参考。
|
2月前
|
Android开发 Kotlin
Android面试题之Kotlin中如何实现串行和并行任务?
本文介绍了 Kotlin 中 `async` 和 `await` 在并发编程中的应用,包括并行与串行任务的处理方法。并通过示例代码展示了如何启动并收集异步任务的结果。
35 0
|
3月前
|
Java Android开发 UED
安卓应用开发中的内存管理优化技巧
在安卓开发的广阔天地里,内存管理是一块让开发者既爱又恨的领域。它如同一位严苛的考官,时刻考验着开发者的智慧与耐心。然而,只要我们掌握了正确的优化技巧,就能够驯服这位考官,让我们的应用在性能和用户体验上更上一层楼。本文将带你走进内存管理的迷宫,用通俗易懂的语言解读那些看似复杂的优化策略,让你的开发之路更加顺畅。
76 2
|
3月前
|
Java Android开发 开发者
安卓应用开发中的线程管理优化技巧
【9月更文挑战第10天】在安卓开发的海洋里,线程管理犹如航行的风帆,掌握好它,能让应用乘风破浪,反之则可能遭遇性能的暗礁。本文将通过浅显易懂的语言和生动的比喻,带你探索如何优雅地处理安卓中的线程问题,从基础的线程创建到高级的线程池运用,让你的应用运行更加流畅。