【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 , 点击链接可跳转查看完整源码 ;


目录
相关文章
|
4天前
|
Java 数据库 Android开发
【专栏】Kotlin在Android开发中的多线程优化,包括线程池、协程的使用,任务分解、避免阻塞操作以及资源管理
【4月更文挑战第27天】本文探讨了Kotlin在Android开发中的多线程优化,包括线程池、协程的使用,任务分解、避免阻塞操作以及资源管理。通过案例分析展示了网络请求、图像处理和数据库操作的优化实践。同时,文章指出并发编程的挑战,如性能评估、调试及兼容性问题,并强调了多线程优化对提升应用性能的重要性。开发者应持续学习和探索新的优化策略,以适应移动应用市场的竞争需求。
|
2天前
|
缓存 程序员 定位技术
Android Studio 插件,那些被大厂优化的程序员们
Android Studio 插件,那些被大厂优化的程序员们
|
2天前
|
设计模式 算法 前端开发
Android面经分享,失业两个月,五一节前拿到Offer,设计思想与代码质量优化+程序性能优化+开发效率优化
Android面经分享,失业两个月,五一节前拿到Offer,设计思想与代码质量优化+程序性能优化+开发效率优化
|
3天前
|
移动开发 监控 Android开发
构建高效安卓应用:Kotlin 协程的实践与优化
【5月更文挑战第16天】 在移动开发领域,性能优化一直是开发者们追求的重要目标。特别是对于安卓平台来说,由于设备多样性和系统资源的限制,如何提升应用的响应性和流畅度成为了一个关键议题。近年来,Kotlin 语言因其简洁、安全和高效的特点,在安卓开发中得到了广泛的应用。其中,Kotlin 协程作为一种轻量级的并发解决方案,为异步编程提供了强大支持,成为提升安卓应用性能的有效手段。本文将深入探讨 Kotlin 协程在安卓开发中的应用实践,以及通过合理设计和使用协程来优化应用性能的策略。
17 8
|
4天前
|
缓存 移动开发 Android开发
Android 应用性能优化实践
【5月更文挑战第15天】 在移动开发领域,应用的性能直接关系到用户体验和产品的市场表现。特别是对于安卓平台,设备的多样性和应用生态环境的复杂性使得性能优化成为开发者的一项重要技能。本文将深入探讨针对安卓应用的性能瓶颈识别、分析方法以及具体的优化策略,旨在为开发者提供一套实用的性能提升解决方案。
|
4天前
|
移动开发 测试技术 Android开发
构建高效Android应用:从优化用户体验到提升性能表现
【5月更文挑战第15天】 在移动开发领域,一个成功的Android应用不仅需要具备吸引用户的功能,更应提供流畅和高效的用户体验。随着技术的不断进步,开发者面临着将先进技术集成到现有架构中以提高应用性能的挑战。本文将深入探讨如何通过最新的Android框架和工具来优化应用性能,包括对UI的响应性、内存管理以及多线程处理等关键方面的改进,旨在帮助开发者构建出更加强大、快速且稳定的Android应用。
|
4天前
|
缓存 Android开发 UED
构建高效Android应用:从优化用户体验到提升性能
【5月更文挑战第15天】 在移动开发领域,构建一个高效的Android应用不仅仅意味着实现功能,还要确保流畅的用户体验和出色的性能。本文将深入探讨如何通过界面优化、代码整洁、资源管理和多线程处理等技术手段来提升Android应用的整体效率。我们将透过实际案例,揭示常见性能瓶颈的成因,并提供相应的解决方案。此外,文章还会涵盖最新的Android Studio工具和Lint检查的使用,帮助开发者早期发现潜在问题。
|
4天前
|
缓存 Java Android开发
Android应用性能优化实战
【5月更文挑战第14天】 在竞争激烈的应用市场中,一个流畅、高效的应用能显著提升用户体验并增强用户黏性。本文深入探讨了针对安卓平台进行应用性能优化的策略与实践,从内存管理到多线程处理,再到布局渲染和网络请求的优化,旨在为开发者提供一套全面的优化工具箱。通过分析常见的性能瓶颈并结合最新的Android技术动态,我们不仅讨论理论,还将分享具体的代码示例和改进方法,帮助开发者在实际应用中实现性能提升。
|
4天前
|
移动开发 数据处理 Android开发
构建高效Android应用:Kotlin协程的实践与优化策略
【5月更文挑战第14天】在移动开发领域,性能优化和资源管理是提升用户体验的关键因素之一。随着Kotlin语言的普及,其异步编程解决方案——协程,已经成为Android开发者手中的强大工具。本文将深入探讨Kotlin协程在Android应用中的实践方法,分析其在处理异步任务时带来的优势,并提出一系列优化策略,帮助开发者构建更加高效、响应迅速的Android应用。通过具体案例分析和性能对比,我们将展示如何充分利用协程来简化代码结构,提高应用性能,并确保用户界面的流畅性。
|
4天前
|
存储 传感器 Android开发
构建高效Android应用:从优化布局到提升性能
【5月更文挑战第13天】 在竞争激烈的移动应用市场中,一个高效的Android应用不仅需要具备直观的用户界面和丰富的功能,还要确保流畅的性能和快速的响应时间。本文将深入探讨如何通过优化布局设计、减少资源消耗以及利用系统提供的API来提升Android应用的性能。我们将分析布局优化的策略,讨论内存使用的常见陷阱,并介绍异步处理和电池寿命的考量。这些技术的综合运用将帮助开发者构建出既美观又高效的Android应用。