【Android 电量优化】电量优化 ( JobScheduler | JobService | AsyncTask )
文章目錄
- 一、JobScheduler 使用流程
- 二、AsyncTask 簡介
- 三、JobScheduler 開發(fā)流程
- 四、JobScheduler 代碼示例
- 1、JobScheduleManager 代碼示例
- 2、JobService 與 AsyncTask 代碼示例
- 3、AndroidManifest.xml 配置
- 4、執(zhí)行結(jié)果
- 五、源碼及資源下載
一、JobScheduler 使用流程
JobScheduler 使用流程 :
① 獲取 JobScheduler 服務(wù) : 從 Context 對象中 , 調(diào)用 getSystemService 方法跨進程獲取 ;
mJobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);② 創(chuàng)建 JobInfo 任務(wù)信息 :
//創(chuàng)建一個任務(wù) JobInfo jobInfo = newJobInfo.Builder(0, // 任務(wù) id 為 0new ComponentName(mContext, BpJobService.class)).setRequiresCharging(true) // 要求在充電時執(zhí)行.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) // 非蜂窩網(wǎng)絡(luò)執(zhí)行.setExtras(extras).build();③ 提交任務(wù) :
mJobScheduler.schedule(jobInfo);④ 執(zhí)行任務(wù) : 在 JobService 的 onStartJob 方法中 , 會由系統(tǒng)在合適的時間 , 執(zhí)行相關(guān)任務(wù) ;
public class BpJobService extends JobService {@Overridepublic boolean onStartJob(JobParameters params) {// 啟動 AsyncTask 異步任務(wù)處理工作new JobAsyncTask().execute(params);return false;}// ... 省略部分代碼 }二、AsyncTask 簡介
在 JobScheduler 提交任務(wù)后 , 系統(tǒng)會在 JobService 中執(zhí)行相應(yīng)的任務(wù) , 執(zhí)行的時機由系統(tǒng)選擇 ;
系統(tǒng)回調(diào) JobService 服務(wù)中的 onStartJob 方法時 , 由用戶自行執(zhí)行相應(yīng)的任務(wù) , 一般是使用 AsyncTask 來執(zhí)行相應(yīng)任務(wù) ;
1 . AsyncTask<JobParameters, Void, Void> 三個泛型解析
- 泛型 111 : 異步任務(wù)開始時 , execute 方法傳入的參數(shù)類型
- 泛型 222 : 異步任務(wù)執(zhí)行時 , 進度值類型
- 泛型 333 : 異步任務(wù)結(jié)束時 , 結(jié)果類型
2 . AsyncTask 444 個方法解析 :
- onPreExecute : doInBackground 之前執(zhí)行的方法, 一般在該方法中執(zhí)行初始化操作 ( 主線程, 可以更新 UI )
- doInBackground : 主要的耗時操作是在該方法中執(zhí)行的 ( 非主線程, 不能更新 UI )
- onProgressUpdate : 在 doInBackground 中調(diào)用了 publishProgress 方法, 就會回調(diào)該方法 , 一般情況下是在該方法中執(zhí)行更新 UI 的操作 ( 主線程, 可以更新 UI )
- onPostExecute : doInBackground 執(zhí)行完畢后 , 調(diào)用 return 方法后 , 該方法會被調(diào)用 ( 主線程, 可以更新 UI )
執(zhí)行順序 : onPreExecute -> doInBackground -> onProgressUpdate -> onPostExecute
三、JobScheduler 開發(fā)流程
1 . 任務(wù)管理類 : 開發(fā) JobScheduleManager 管理類 , 該類負責(zé)與 Service 服務(wù)中的需求對接 , 接收 Service 服務(wù)中的添加任務(wù)的需求 , 將任務(wù)操作轉(zhuǎn)為參數(shù) , 并提交到系統(tǒng) JobScheduler 中 ;
2 . 任務(wù)執(zhí)行服務(wù) : 開發(fā) JobService 服務(wù) , 該服務(wù)是執(zhí)行具體的任務(wù)的類 , 在該類中 , 接收到系統(tǒng)調(diào)度的任務(wù)參數(shù) , 在 onStartJob 方法中解析這些參數(shù) , 并創(chuàng)建 AsyncTask 執(zhí)行對應(yīng)的任務(wù) ;
3 . 添加任務(wù) : 在一個第三方 Service 服務(wù)中 , 調(diào)用 JobScheduleManager 類添加任務(wù) , 系統(tǒng)會自動回調(diào)分配執(zhí)行任務(wù) , 在 JobService 中的 onStartJob 方法中執(zhí)行任務(wù) ;
四、JobScheduler 代碼示例
1、JobScheduleManager 代碼示例
該類主要用于管理 JobScheduler , 初始化 JobScheduler , 處理添加任務(wù)的選項等操作 , 如任務(wù)執(zhí)行時機 , 執(zhí)行需求 等 ;
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";/*** 將不緊急的任務(wù)調(diào)度到更合適的時機進行處理* 如充電時 , 如 WIFI 連接時* 1. 避免頻繁由于執(zhí)行單次任務(wù) , 喚醒硬件模塊 , 造成電量浪費* 2. 避免在不合適的時機執(zhí)行耗電任務(wù) , 如使用蜂窩網(wǎng)絡(luò)在不合適的時候更新軟件*/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, "添加任務(wù) : " + currentJobData);// 查找 id 為 0 的 任務(wù)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;}}}// 獲取任務(wù)執(zhí)行數(shù)據(jù)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);//創(chuàng)建一個任務(wù)JobInfo jobInfo = newJobInfo.Builder(0, // 任務(wù) id 為 0new ComponentName(mContext, BpJobService.class)).setRequiresCharging(true) // 要求在充電時執(zhí)行.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) // 非蜂窩網(wǎng)絡(luò)執(zhí)行.setExtras(extras).build();// 將任務(wù)提交到隊列中mJobScheduler.schedule(jobInfo);}} }2、JobService 與 AsyncTask 代碼示例
JobService 與 AsyncTask 代碼示例 :
注意 JobService 的兩個方法 onStartJob , onStopJob 的調(diào)用時機 , 與返回值含義 ;
注意 AsyncTask 定義時三個泛型的含義 , onPreExecute , doInBackground , onProgressUpdate , onPostExecute 四個方法的調(diào)用時機 ;
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 任務(wù)正要被執(zhí)行, 需要開始執(zhí)行任務(wù)* false 任務(wù)執(zhí)行完畢*/@Overridepublic boolean onStartJob(JobParameters params) {// 啟動 AsyncTask 異步任務(wù)處理工作new JobAsyncTask().execute(params);return false;}/**** @param params* @return*/@Overridepublic boolean onStopJob(JobParameters params) {return false;}/*** AsyncTask<JobParameters, Void, Void> 三個泛型解析* -- 1. 異步任務(wù)開始時 , execute 方法傳入的參數(shù)類型* -- 2. 異步任務(wù)執(zhí)行時 , 進度值類型* -- 3. 異步任務(wù)結(jié)束時 , 結(jié)果類型*/class JobAsyncTask extends AsyncTask<JobParameters, Void, Void> {/*** doInBackground 之前執(zhí)行的方法, 一般在該方法中執(zhí)行初始化操作* ( 主線程, 可以更新 UI )*/@Overrideprotected void onPreExecute() {super.onPreExecute();}/*** 主要的耗時操作是在該方法中執(zhí)行的* ( 非主線程, 不能更新 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 執(zhí)行 : " + jobData);return null;}/*** 在 doInBackground 中調(diào)用了 publishProgress 方法, 就會回調(diào)該方法* 一般情況下是在該方法中執(zhí)行更新 UI 的操作* ( 主線程, 可以更新 UI )* @param values*/@Overrideprotected void onProgressUpdate(Void... values) {super.onProgressUpdate(values);}/*** doInBackground 執(zhí)行完畢后 , 調(diào)用 return 方法后 , 該方法會被調(diào)用* ( 主線程, 可以更新 UI )* @param aVoid*/@Overrideprotected void onPostExecute(Void aVoid) {super.onPostExecute(aVoid);}} }3、AndroidManifest.xml 配置
主要是配置 AlarmManagerService 服務(wù) 和 BpJobService 服務(wù) ;
注意為 BpJobService 服務(wù)聲明 android.permission.BIND_JOB_SERVICE 權(quán)限 ;
<?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><!-- 網(wǎng)絡(luò)狀態(tài)改變 --><action android:name="android.intent.action.CONNECTIVITY_CHANGE" /></intent-filter></receiver><!-- WeakLock 保持 CPU 喚醒的 Service 服務(wù) --><serviceandroid:name=".WeakLockService"android:process=":weaklock" /><!-- AlarmManager 保持 CPU 喚醒的 Service 服務(wù) --><serviceandroid:name=".AlarmManagerService"android:process=":alrmmanager" /><!-- JobScheduler 服務(wù) --><serviceandroid:name=".BpJobService"android:process=":jobservice"android:permission="android.permission.BIND_JOB_SERVICE"/></application></manifest>4、執(zhí)行結(jié)果
執(zhí)行結(jié)果 :
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: 添加任務(wù) : ACTION(1594105279057) 2020-07-07 15:01:19.239 11158-11214/kim.hsl.bp:jobservice I/Battery_Performance.BpJobService: JobAsyncTask 執(zhí)行 : 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: 添加任務(wù) : ACTION(1594105358986) 2020-07-07 15:02:38.997 11158-11214/kim.hsl.bp:jobservice I/Battery_Performance.BpJobService: JobAsyncTask 執(zhí)行 : 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
總結(jié)
以上是生活随笔為你收集整理的【Android 电量优化】电量优化 ( JobScheduler | JobService | AsyncTask )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 电量优化】电量优化 (
- 下一篇: 【Android 电量优化】JobSch