文章目录

  • 一、JobScheduler 使用流程
  • 二、AsyncTask 简介
  • 三、JobScheduler 开发流程
  • 四、JobScheduler 代码示例
    • 1、JobScheduleManager 代码示例
    • 2、JobService 与 AsyncTask 代码示例
    • 3、AndroidManifest.xml 配置
    • 4、执行结果
  • 五、源码及资源下载

一、JobScheduler 使用流程


JobScheduler 使用流程 :

① 获取 JobScheduler 服务 : 从 Context 对象中 , 调用 getSystemService 方法跨进程获取 ;

mJobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);

② 创建 JobInfo 任务信息 :

//创建一个任务
JobInfo jobInfo = newJobInfo.Builder(0,  // 任务 id 为 0new ComponentName(mContext, BpJobService.class)).setRequiresCharging(true)  // 要求在充电时执行.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) // 非蜂窝网络执行.setExtras(extras).build();

③ 提交任务 :

mJobScheduler.schedule(jobInfo);

④ 执行任务 : 在 JobService 的 onStartJob 方法中 , 会由系统在合适的时间 , 执行相关任务 ;

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

二、AsyncTask 简介


在 JobScheduler 提交任务后 , 系统会在 JobService 中执行相应的任务 , 执行的时机由系统选择 ;

系统回调 JobService 服务中的 onStartJob 方法时 , 由用户自行执行相应的任务 , 一般是使用 AsyncTask 来执行相应任务 ;

1 . AsyncTask<JobParameters, Void, Void> 三个泛型解析

  • 泛型 111 : 异步任务开始时 , execute 方法传入的参数类型
  • 泛型 222 : 异步任务执行时 , 进度值类型
  • 泛型 333 : 异步任务结束时 , 结果类型

2 . AsyncTask 444 个方法解析 :

  • onPreExecute : doInBackground 之前执行的方法, 一般在该方法中执行初始化操作 ( 主线程, 可以更新 UI )
  • doInBackground : 主要的耗时操作是在该方法中执行的 ( 非主线程, 不能更新 UI )
  • onProgressUpdate : 在 doInBackground 中调用了 publishProgress 方法, 就会回调该方法 , 一般情况下是在该方法中执行更新 UI 的操作 ( 主线程, 可以更新 UI )
  • onPostExecute : doInBackground 执行完毕后 , 调用 return 方法后 , 该方法会被调用 ( 主线程, 可以更新 UI )

执行顺序 : onPreExecute -> doInBackground -> onProgressUpdate -> onPostExecute

三、JobScheduler 开发流程


1 . 任务管理类 : 开发 JobScheduleManager 管理类 , 该类负责与 Service 服务中的需求对接 , 接收 Service 服务中的添加任务的需求 , 将任务操作转为参数 , 并提交到系统 JobScheduler 中 ;

2 . 任务执行服务 : 开发 JobService 服务 , 该服务是执行具体的任务的类 , 在该类中 , 接收到系统调度的任务参数 , 在 onStartJob 方法中解析这些参数 , 并创建 AsyncTask 执行对应的任务 ;

3 . 添加任务 : 在一个第三方 Service 服务中 , 调用 JobScheduleManager 类添加任务 , 系统会自动回调分配执行任务 , 在 JobService 中的 onStartJob 方法中执行任务 ;

四、JobScheduler 代码示例


1、JobScheduleManager 代码示例

该类主要用于管理 JobScheduler , 初始化 JobScheduler , 处理添加任务的选项等操作 , 如任务执行时机 , 执行需求 等 ;

package kim.hsl.bp;import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
import android.os.Build;
import android.os.PersistableBundle;
import android.util.Log;import java.util.List;public class JobScheduleManager {public static final String TAG = "JobScheduleManager";/*** 将不紧急的任务调度到更合适的时机进行处理* 如充电时 , 如 WIFI 连接时* 1. 避免频繁由于执行单次任务 , 唤醒硬件模块 , 造成电量浪费* 2. 避免在不合适的时机执行耗电任务 , 如使用蜂窝网络在不合适的时候更新软件*/private JobScheduler mJobScheduler;/*** 上下文对象*/private Context mContext;/*单例模式*/private static JobScheduleManager mInstance;private JobScheduleManager(){}public static JobScheduleManager getInstance(){if(mInstance == null){mInstance = new JobScheduleManager();}return mInstance;}public void init(Context context){this.mContext = context;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {mJobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);}}public void addJob(String currentJobData){if(mJobScheduler == null){return;}Log.i(TAG, "添加任务 : " + currentJobData);// 查找 id 为 0 的 任务JobInfo pendingJob = null;if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){pendingJob = mJobScheduler.getPendingJob(0);}else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {List<JobInfo> allPendingJobs = mJobScheduler.getAllPendingJobs();for(JobInfo info : allPendingJobs){if(info.getId() == 0){pendingJob = info;break;}}}// 获取任务执行数据String historyJobData = "";if(pendingJob != null){if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {PersistableBundle extras = pendingJob.getExtras();historyJobData = extras.getString("JOB_DATA");mJobScheduler.cancel(0);}}if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {PersistableBundle extras = new PersistableBundle();extras.putString("JOB_DATA", currentJobData + "$" + historyJobData);//创建一个任务JobInfo jobInfo = newJobInfo.Builder(0,  // 任务 id 为 0new ComponentName(mContext, BpJobService.class)).setRequiresCharging(true)  // 要求在充电时执行.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) // 非蜂窝网络执行.setExtras(extras).build();// 将任务提交到队列中mJobScheduler.schedule(jobInfo);}}
}

2、JobService 与 AsyncTask 代码示例

JobService 与 AsyncTask 代码示例 :

注意 JobService 的两个方法 onStartJob , onStopJob 的调用时机 , 与返回值含义 ;

注意 AsyncTask 定义时三个泛型的含义 , onPreExecute , doInBackground , onProgressUpdate , onPostExecute 四个方法的调用时机 ;

package kim.hsl.bp;import android.app.job.JobParameters;
import android.app.job.JobService;
import android.os.AsyncTask;
import android.os.Build;
import android.os.PersistableBundle;
import android.util.Log;import androidx.annotation.RequiresApi;@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class BpJobService extends JobService {public static final String TAG = "Battery_Performance.BpJobService";/**** @param params* @return*      true 任务正要被执行, 需要开始执行任务*      false 任务执行完毕*/@Overridepublic boolean onStartJob(JobParameters params) {// 启动 AsyncTask 异步任务处理工作new JobAsyncTask().execute(params);return false;}/**** @param params* @return*/@Overridepublic boolean onStopJob(JobParameters params) {return false;}/*** AsyncTask<JobParameters, Void, Void> 三个泛型解析* -- 1. 异步任务开始时 , execute 方法传入的参数类型* -- 2. 异步任务执行时 , 进度值类型* -- 3. 异步任务结束时 , 结果类型*/class JobAsyncTask extends AsyncTask<JobParameters, Void, Void> {/*** doInBackground 之前执行的方法, 一般在该方法中执行初始化操作* ( 主线程, 可以更新 UI )*/@Overrideprotected void onPreExecute() {super.onPreExecute();}/*** 主要的耗时操作是在该方法中执行的* ( 非主线程, 不能更新 UI )* @param jobParameters* @return*/@Overrideprotected Void doInBackground(JobParameters... jobParameters) {JobParameters parameters = jobParameters[0];PersistableBundle extras = parameters.getExtras();String jobData = extras.getString("JOB_DATA");Log.i(TAG, "JobAsyncTask 执行 : " + jobData);return null;}/*** 在 doInBackground 中调用了 publishProgress 方法, 就会回调该方法* 一般情况下是在该方法中执行更新 UI 的操作* ( 主线程, 可以更新 UI )* @param values*/@Overrideprotected void onProgressUpdate(Void... values) {super.onProgressUpdate(values);}/*** doInBackground 执行完毕后 , 调用 return 方法后 , 该方法会被调用* ( 主线程, 可以更新 UI )* @param aVoid*/@Overrideprotected void onPostExecute(Void aVoid) {super.onPostExecute(aVoid);}}
}

3、AndroidManifest.xml 配置

主要是配置 AlarmManagerService 服务 和 BpJobService 服务 ;

注意为 BpJobService 服务声明 android.permission.BIND_JOB_SERVICE 权限 ;

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="kim.hsl.bp"><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission><uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission><uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission><uses-permission android:name="android.permission.INTERNET"></uses-permission><uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.WAKE_LOCK" /><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><receiver android:name=".BatteryReceiver" ><intent-filter><!-- 充电线插上 --><action android:name="android.intent.action.ACTION_POWER_CONNECTED" /><!-- 充电线拔出 --><action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" /></intent-filter></receiver><receiver android:name=".WifiReceiver" ><intent-filter><!-- 网络状态改变 --><action android:name="android.intent.action.CONNECTIVITY_CHANGE" /></intent-filter></receiver><!-- WeakLock 保持 CPU 唤醒的 Service 服务 --><serviceandroid:name=".WeakLockService"android:process=":weaklock" /><!-- AlarmManager 保持 CPU 唤醒的 Service 服务 --><serviceandroid:name=".AlarmManagerService"android:process=":alrmmanager" /><!-- JobScheduler 服务 --><serviceandroid:name=".BpJobService"android:process=":jobservice"android:permission="android.permission.BIND_JOB_SERVICE"/></application></manifest>

4、执行结果

执行结果 :

2020-07-07 15:00:58.189 11091-11091/kim.hsl.bp:alrmmanager I/Battery_Performance.AlarmManagerService: AlarmManagerService onCreate2020-07-07 15:01:19.056 11091-11091/kim.hsl.bp:alrmmanager I/Battery_Performance.AlarmManagerService: receiver ACTION
2020-07-07 15:01:19.057 11091-11091/kim.hsl.bp:alrmmanager I/Battery_Performance.JobScheduleManager: 添加任务 : ACTION(1594105279057)
2020-07-07 15:01:19.239 11158-11214/kim.hsl.bp:jobservice I/Battery_Performance.BpJobService: JobAsyncTask 执行 : ACTION(1594105279057)$2020-07-07 15:02:38.985 11091-11091/kim.hsl.bp:alrmmanager I/Battery_Performance.AlarmManagerService: receiver ACTION
2020-07-07 15:02:38.986 11091-11091/kim.hsl.bp:alrmmanager I/Battery_Performance.JobScheduleManager: 添加任务 : ACTION(1594105358986)
2020-07-07 15:02:38.997 11158-11214/kim.hsl.bp:jobservice I/Battery_Performance.BpJobService: JobAsyncTask 执行 : ACTION(1594105358986)$
2020-07-07 15:03:19.058 11091-11091/kim.hsl.bp:alrmmanager I/Battery_Performance.AlarmManagerService: receiver ACTION

五、源码及资源下载


源码及资源下载地址 :

  • ① GitHub 工程地址 : Battery_Performance

  • ② 使用 AlarmManager 保持 CPU 唤醒 Service 代码地址 : AlarmManagerService.java

  • ③ JobScheduleManager.java 代码地址 : JobScheduleManager.java

  • ④ BpJobService.java 代码地址 : BpJobService.java

  • ⑤ AndroidManifest.xml 配置文件地址 : AndroidManifest.xml

【Android 电量优化】电量优化 ( JobScheduler | JobService | AsyncTask )相关推荐

  1. android 6.0电池优化,Android 优化——电量优化

    WakeLock Android 系统本身为了优化电量的使用,会在没有操作时进入休眠状态,来节省电量.当然,为了便于开发(很多应用不可避免的希望在灭屏后还能运行一些事儿,或是要保持屏幕一直亮着--比如 ...

  2. Android9.0 P 电源管理android各版本电量优化功能策略

    针对电量优化android的改动 在最近几个android版本中已存在的电量优化功能基础上,Android 9 引入了一些新功能来持续改进设备电源管理,以确保将系统资源提供给最需要它们的应用. 近几个 ...

  3. android os跑电量咋关,android 优化耗电量

    作为app开发者,或许很少有人会注意app对电量的损耗,但是用户对电量可是很敏感的,app做好电量损耗的优化会为自己的app加分不少. 如果是一个好的负责任的开发者,就应该限制app对电量的影响,当没 ...

  4. android系统电量优化,基于Android系统网络耗电量优化方法的.pdf

    基于Android系统网络耗电量优化方法的 2012年第10期,第 45卷 通 信 技 术 Vol.45,No.10,2012 总第250期 Communications Technology No. ...

  5. iOS 开发之优化电量

    ????????关注后回复 "进群" ,拉你进程序员交流群???????? 在现如今的开发中, 电量消耗是一个应用运行效果的一个重要的衡量标准,尤其是直播,运动应用.设备中的每个硬 ...

  6. Android高手笔记 - 耗电优化

    耗电的背景知识 电池技术:电池容量,充电时间,寿命,安全性: 电量和硬件:应用程序不会直接去消耗电池,而是通过使用硬件模块消耗相应的电能:CPU.屏幕.WiFi 和数据网络.GPS 以及音视频通话都是 ...

  7. 转:Android应用开发性能优化完全分析

    转自:http://blog.csdn.net/yanbober/article/details/48394201 1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜 ...

  8. Android应用开发性能优化完全分析

    1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关于性能的建议,感觉大家你一总结.我一总结的都说到了很多优化注意事项,但是看过这些文章后大多数存在一个问题就是只 ...

  9. 关于android性能,内存优化 http://www.cnblogs.com/zyw-205520/archive/2013/02/17/2914190.html

     随着技术的发展,智能手机硬件配置越来越高,可是它和现在的PC相比,其运算能力,续航能力,存储空间等都还是受到很大的限制,同时用户对手机的体验要  求远远高于PC的桌面应用程序.以上理由,足以需要 ...

最新文章

  1. 机器学习必知的8大神经网络架构和原理
  2. python从入门到精通书-Python从入门到精通(资源汇总)
  3. Java容器--Map
  4. 怎么查计算机网络硬件配置,如何查看电脑本机的硬件配置?
  5. 解决Eclipse中文乱码的方法
  6. 输出字母沙漏+对称字符串
  7. LeetCode-148:排序链表
  8. kafka数据可靠传输
  9. left join,right join,inner join,full join之间的区别
  10. 计算机操作系统(吴企渊)pdf
  11. SVN(三)利用 IntelliJ IDEA 进行代码对比的方法
  12. Mugeda(木疙瘩)H5案例课—拍拍员工被玩坏了-岑远科-专题视频课程
  13. Linux沙箱技术介绍
  14. 450米、90米、30米全国地形图DEM数据对比与分享
  15. android 电源管理
  16. 直播弹幕系统(三)- 直播在线人数统计
  17. 三种通信方式——单工、半双工和双工通信
  18. django app服务器搭建
  19. 正则表达式校验邮箱号、手机号、身份证号码等等
  20. windows 更新失败 你的设备中缺少重要的安全和质量修复。

热门文章

  1. 解决虚拟机vmware安装64位系统“此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态”的问题...
  2. Windows批处理
  3. Python自动化一--接口测试基础知识,jmeter操作介绍
  4. [转]批处理for命令使用指南
  5. WPF界面设计技巧(3)—实现不规则动画按钮
  6. centos 安装 erlang
  7. jsp cookie 中文乱码 的解决方法
  8. tomcat启动前端项目
  9. LeetCode10.正则表达式匹配 JavaScript
  10. 基于Mybatis,处理多表联合获取