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

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

文章目录

一、ConnectivityController 连接控制器引入

二、ConnectivityController 构造方法解析 ( 注册接收者 )

三、mConnectivityReceiver 广播接收者

四、updateTrackedJobs 更新监控任务

五、ConnectivityController 部分源码注释



推荐代码查看网站 :


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


http://androidxref.com/




上一篇博客 【Android 电量优化】JobScheduler 源码分析 ( JobSchedulerService 源码分析 | Android 源码在线网址推荐 ) 中讲解了JobScheduler 调用 schedule 方法底层调用 :


该方法最终调用的是 JobSchedulerService 中的 int schedule(JobInfo job, int uId) 方法

在 schedule 方法中调用了 scheduleAsPackage 方法

在 scheduleAsPackage 方法中调用了 startTrackingJob 方法

在 startTrackingJob 中 , 调用了每个 StateController 状态控制器的 maybeStartTrackingJobLocked 的方法 ;

本篇博客中讲解了 ConnectivityController 中对任务状态的处理 ;






一、ConnectivityController 连接控制器引入


上一篇博客中在 JobSchedulerService 中最终在 startTrackingJob 方法中 , 调用了 StateController 控制器的 maybeStartTrackingJobLocked 方法 ;


这里以 ConnectivityController 连接控制器为例 , 该类是 StateController 的子类 , 其在 JobSchedulerService 中相关源码如下 :


/** 控制器集合 , 提醒该 Service 服务区更新任务. */
      List<StateController> mControllers;
        // 后续会遍历该集合 , 遍历出的元素会调用 maybeStartTrackingJobLocked 方法
        mControllers = new ArrayList<StateController>();
        // 网络控制器
        mControllers.add(ConnectivityController.get(this));
  // 调用控制器的 maybeStartTrackingJobLocked 函数 
        controller.maybeStartTrackingJobLocked(jobStatus, lastJob);


在 ConnectivityController 中的 void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) 方法 , 该方法作用是更新所有该控制器追踪的任务 , 被追踪的任务都在 ArrayList<JobStatus> mTrackedJobs 集合中 , 该集合在类成员变量中维护 ;


会对传入的任务状态 JobStatus jobStatus 参数进行一系列判定 , 如果判定通过 , 就会执行






二、ConnectivityController 构造方法解析 ( 注册接收者 )


在 ConnectivityController(StateChangedListener stateChangedListener, Context context, Object lock) 构造方法中 , 注册了广播接收者 , 接收 ConnectivityManager.CONNECTIVITY_ACTION 广播 , 这是监听网络状态改变发出的广播 ;


 // 注册广播接收者 , 接收 ConnectivityManager.CONNECTIVITY_ACTION 广播 , 这是监听网络状态改变发出的广播

 

final IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
        mContext.registerReceiverAsUser(
                mConnectivityReceiver, UserHandle.SYSTEM, intentFilter, null, null);






三、mConnectivityReceiver 广播接收者


在 mConnectivityReceiver 广播接收者中 , 接收到 ConnectivityManager.CONNECTIVITY_ACTION 广播 , 网络状态改变后 , 就会调 updateTrackedJobs(-1) 函数 ;


   

public void onReceive(Context context, Intent intent) {
          // 接收到 ConnectivityManager.CONNECTIVITY_ACTION 广播
          // 网络状态改变后 , 就会调用该函数 
            updateTrackedJobs(-1);
        }


四、updateTrackedJobs 更新监控任务


void updateTrackedJobs(int uid) 方法的作用是 : 更新所有该控制器追踪的任务 , 被追踪的任务都在 ArrayList mTrackedJobs 集合中 ;


int uid 参数含义 : 更新该 uid 对应的任务 , 如果传入 -1 那么就是更新所有的被追踪任务 ;



在该方法中 , 遍历所有的被监听的任务集合 , ArrayList mTrackedJobs , 如果有一个任务发生改变 , 就回调 状态改变监听器 mStateChangedListener , 该 mStateChangedListener 定义在父类 StateController 中 ; mStateChangedListener 实际上是 JobSchedulerService ;


mStateChangedListener.onControllerStateChanged()

;






五、ConnectivityController 部分源码注释


/**
 * 处理连接状态改变
 * 每个应用可以有不同的默认网络或不同的连接状态 , 根据用户需要的网络策略 , 因此我们需要检查每个 uid 要素的约束 .
 */
public class ConnectivityController extends StateController implements
        ConnectivityManager.OnNetworkActiveListener {
    // 连接管理器系统服务
    private final ConnectivityManager mConnManager;
    // 网络策略管理器系统服务
    private final NetworkPolicyManager mNetPolicyManager;
    // 任务状态集合
    @GuardedBy("mLock")
    private final ArrayList<JobStatus> mTrackedJobs = new ArrayList<JobStatus>();
    // 连接控制器构造函数 
    private ConnectivityController(StateChangedListener stateChangedListener, Context context,
            Object lock) {
        // 调用父类的 StateController 的构造方法
        super(stateChangedListener, context, lock);
  // 获取连接管理器系统服务
        mConnManager = mContext.getSystemService(ConnectivityManager.class);
        // 获取网络策略系统服务 
        mNetPolicyManager = mContext.getSystemService(NetworkPolicyManager.class);
  // 注册广播接收者 , 接收 ConnectivityManager.CONNECTIVITY_ACTION 广播 , 这是监听网络状态改变发出的广播
        final IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
        mContext.registerReceiverAsUser(
                mConnectivityReceiver, UserHandle.SYSTEM, intentFilter, null, null);
  // 注册网络策略监听器
        mNetPolicyManager.registerListener(mNetPolicyListener);
    }
    @Override
    public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
      // 判断任务的一系列状态
        if (jobStatus.hasConnectivityConstraint() || jobStatus.hasUnmeteredConstraint()
                || jobStatus.hasNotRoamingConstraint()) {
            updateConstraintsSatisfied(jobStatus);
            // 将任务状态放入 ArrayList<JobStatus> mTrackedJobs 集合中
            mTrackedJobs.add(jobStatus);
        }
    }
  // 在构造函数中注册的广播接收者 
    private BroadcastReceiver mConnectivityReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
          // 接收到 ConnectivityManager.CONNECTIVITY_ACTION 广播
          // 网络状态改变后 , 就会调用该函数 
            updateTrackedJobs(-1);
        }
    };
    /**
     * 更新所有该控制器追踪的任务 ;
     * 被追踪的任务都在 ArrayList<JobStatus> mTrackedJobs 集合中
     *
     * @param uid 更新该 uid 对应的任务 , 如果传入 -1 那么就是更新所有的被追踪任务
     */
    private void updateTrackedJobs(int uid) {
        synchronized (mLock) {
            boolean changed = false;
            // 遍历所有的被监听的任务集合 , ArrayList<JobStatus> mTrackedJobs  
            for (int i = 0; i < mTrackedJobs.size(); i++) {
                final JobStatus js = mTrackedJobs.get(i);
                if (uid == -1 || uid == js.getSourceUid()) {
                    changed |= updateConstraintsSatisfied(js);
                }
            }
            // 如果判断的改变为 true , 就回调 状态改变监听器 mStateChangedListener
            // 该 mStateChangedListener 定义在父类 StateController 中 
            // 状态控制器创建时 , 会传入 mStateChangedListener 
            if (changed) {
                mStateChangedListener.onControllerStateChanged();
            }
        }
    }
}


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


目录
相关文章
|
20天前
|
缓存 编解码 Android开发
Android内存优化之图片优化
本文主要探讨Android开发中的图片优化问题,包括图片优化的重要性、OOM错误的成因及解决方法、Android支持的图片格式及其特点。同时介绍了图片储存优化的三种方式:尺寸优化、质量压缩和内存重用,并详细讲解了相关的实现方法与属性。此外,还分析了图片加载优化策略,如异步加载、缓存机制、懒加载等,并结合多级缓存流程提升性能。最后对比了几大主流图片加载框架(Universal ImageLoader、Picasso、Glide、Fresco)的特点与适用场景,重点推荐Fresco在处理大图、动图时的优异表现。这些内容为开发者提供了全面的图片优化解决方案。
|
3月前
|
JavaScript Linux 网络安全
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
549 76
|
5月前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
257 12
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
|
8月前
|
调度 Android开发 开发者
构建高效Android应用:探究Kotlin多线程优化策略
【10月更文挑战第11天】本文探讨了如何在Kotlin中实现高效的多线程方案,特别是在Android应用开发中。通过介绍Kotlin协程的基础知识、异步数据加载的实际案例,以及合理使用不同调度器的方法,帮助开发者提升应用性能和用户体验。
141 4
|
7月前
|
安全 Android开发 iOS开发
深入探索iOS与Android系统的差异性及优化策略
在当今数字化时代,移动操作系统的竞争尤为激烈,其中iOS和Android作为市场上的两大巨头,各自拥有庞大的用户基础和独特的技术特点。本文旨在通过对比分析iOS与Android的核心差异,探讨各自的优势与局限,并提出针对性的优化策略,以期为用户提供更优质的使用体验和为开发者提供有价值的参考。
|
Java Android开发 开发者
【Android 电量优化】JobScheduler 源码分析 ( JobServiceContext 源码分析 | 闭环操作总结 | 用户提交任务 | 广播接收者接受相关广播触发任务执行 )★
【Android 电量优化】JobScheduler 源码分析 ( JobServiceContext 源码分析 | 闭环操作总结 | 用户提交任务 | 广播接收者接受相关广播触发任务执行 )★
257 0
|
Java Android开发
【Android 电量优化】JobScheduler 相关源码分析 ( JobSchedulerService 源码分析 | 任务检查 | 任务执行 )
【Android 电量优化】JobScheduler 相关源码分析 ( JobSchedulerService 源码分析 | 任务检查 | 任务执行 )
187 0
|
Java Android开发
【Android 电量优化】JobScheduler 相关源码分析 ( JobSchedulerService 源码分析 | Android 源码在线网址推荐 )
【Android 电量优化】JobScheduler 相关源码分析 ( JobSchedulerService 源码分析 | Android 源码在线网址推荐 )
246 0
|
13天前
|
安全 Java Android开发
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
41 0
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
|
4月前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
291 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
下一篇
oss创建bucket