1.為了省電函卒,有些工作可以當手機插上電源的時候去處理。
像這些不需要及時地和用戶交互的操作可以放到后面處理虱咧。
比如:360手機助手锚国,當充上電的時候,才去更新App
如何立即獲取手機當前充電狀態(tài)?
//獲取手機充電狀態(tài)
public boolean isPlugged() {
// 通過廣播接收者獲取
IntentFilter intentFilter = new IntentFilter(
Intent.ACTION_BATTERY_CHANGED);
// 獲取Intent绘沉。充電情況在intent中
Intent intent = this.registerReceiver(null, intentFilter);
// 獲取充電狀態(tài)。int值车伞。int可以代表很多狀態(tài)。
int pluggedState = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
// USB充電
boolean usb = pluggedState == BatteryManager.BATTERY_PLUGGED_USB;
// 交流點充電
boolean ac = pluggedState == BatteryManager.BATTERY_PLUGGED_AC;
// 無線充電,當無線充電支持api >= 17
boolean wireless = false;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1) {
wireless = pluggedState == BatteryManager.BATTERY_PLUGGED_WIRELESS;
}
return usb || ac || wireless;
}
2.Wake Lock
在使用該類的時候困曙,必須保證acquire和release是成對出現的慷丽。
因為創(chuàng)建和持有喚醒鎖對電池的續(xù)航有較大的影響鳄哭。如果不釋放WakeLock的話,CPU一直運行杨耙,耗電會非称矗快容握。
3.集中處理算法,JobSchedule/GCM
CUP喚醒時的高峰線:
image.png
從上圖可以看出塑猖。在喚醒的CPU耗電是相對于喚醒之后要高得多得多羊苟。
所以大量高頻次的CPU喚醒及操作感憾,我們最好把這些喚醒和操作集中處理。這樣有利于優(yōu)化電量
我們可以采取一些算法來解決凉倚。
谷歌提供了Jobschedule(5.0Api)/GCM算法來解決。
JobScheduler示例:
JobService
package com.zsj.jobscheduler;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;
import android.annotation.SuppressLint;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.util.Log;
@SuppressLint("NewApi")
public class MyJobScheduler extends JobService {
private static final String LOG_TAG = "zsjJobScheduler";
@Override
public boolean onStartJob(JobParameters params) {
// 這是您實現所有工作邏輯的地方稽寒。 請注意杏糙,這運行
// 在主線程上,所以您將要使用單獨的線程進行異步工作
// false: 該系統(tǒng)假設任何任務運行不需要很長時間并且到方法返回時已經完成宏侍。
// true: 該系統(tǒng)假設任務是需要一些時間并且當任務完成時需要調用jobFinished()告知系統(tǒng)。
// 首先漫蛔,檢查網絡旧蛾,然后嘗試連接。
if (isNetworkConnected()) {
new SimpleDownloadTask().execute(params);
return true;
} else {
Log.i(LOG_TAG, "沒有網絡去工作" + params.getJobId());
}
return false;
}
/**
* 確定設備當前是否在線毯盈。
*/
private boolean isNetworkConnected() {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return (networkInfo != null && networkInfo.isConnected());
}
@Override
public boolean onStopJob(JobParameters params) {
// 如果在調用jobFinished()之前必須停止作業(yè)搂赋,則這個方法益缠。
return false;
}
/**
* 異步任務
*/
private class SimpleDownloadTask extends
AsyncTask<JobParameters, Void, String> {
protected JobParameters mJobParam;
@Override
protected String doInBackground(JobParameters... params) {
mJobParam = params[0];
try {
//做耗時操作
} catch (IOException e) {
return "下載失敗";
}
}
@Override
protected void onPostExecute(String result) {
// job 完成幅慌。
jobFinished(mJobParam, false);
Log.i(LOG_TAG, "獲取結果 : " + result);
}
}
}
調用:
package com.zsj.jobscheduler;
import android.app.Activity;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
private ComponentName mJobService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, MyJobScheduler.class));
mJobService = new ComponentName(this, MyJobScheduler.class);
}
public void jobschedule(View view) {
JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
for (int i = 0; i < 50; i++) {
int jobId = i;
/*
* new JobInfo.Builder(jobId, mJobService)
* 第一個參數為該任務的標識符
* 第二個參數是你希望用來處理該任務的服務對應的ComponentName胰伍,用來啟動該服務
*/
JobInfo job = new JobInfo.Builder(jobId, mJobService)
/*
* setBackoffCriteria(initialBackoffMillis, backoffPolicy)//
* 設置退避/重試策略。當一個任務的調度失敗時需要重試祷杈,所采取的策略渗饮。
* 第一個參數時第一次嘗試重試的等待間隔,單位為毫秒特占。預設的參數有:DEFAULT_INITIAL_BACKOFF_MILLIS.,MAX_BACKOFF_DELAY_MILLIS
* 第二個參數是對應的退避策略云茸,預設的參數有:BACKOFF_POLICY_EXPONENTIAL——指數增長退避策略。BACKOFF_POLICY_LINEAR-線性策略
*/
.setBackoffCriteria(JobInfo.DEFAULT_INITIAL_BACKOFF_MILLIS, JobInfo.BACKOFF_POLICY_EXPONENTIAL)
.setMinimumLatency(60)//設置任務執(zhí)行延遲的時長
// .setPeriodic(long interval)//設置周期懊纳。可以保證在每個間隔之間任務最多只執(zhí)行一次
// .setPeriodic (long interval, long flexMillis) //在周期末的一個flex長度的窗口期()嗤疯,任務都有可能被執(zhí)行
// .setPersisted (boolean isPersisted) 設置當設備重啟后,這個任務是否還保留戏罢。需要RECEIVE_BOOT_COMPLETED權限
/*
* setRequiredNetworkType (int networkType) 設置要求的網絡脚囊,只有連接給定類型的網絡才能執(zhí)行,常用預設值有:
* NETWORK_TYPE_UNMETERED - 免費網絡, NETWORK_TYPE_ANY - 任意網絡
*/
// .setRequiresCharging (boolean requiresCharging) 設置是否需要充電CIA執(zhí)行。默認false
// setRequiresDeviceIdle (boolean requiresDeviceIdle) 設置是否需要設備處于空閑時執(zhí)行讲岁。默認false
.build();//創(chuàng)建對應的JobInfo
jobScheduler.schedule(job);
}
}
}
注冊:
<service
android:name="com.zsj.jobscheduler.MyJobScheduler"
android:permission="android.permission.BIND_JOB_SERVICE" >
</service>
也可參考谷歌官方Demo:https://github.com/googlesamples/android-JobScheduler