一.電池省電優化(Doze和App Standby模式)
從Android6.0開始,系統提供了兩種省電功能(延長電池壽命和使用時間):Doze和App Standby
Doze和App Standby模式會延緩CPU和網絡活動實作節能;
1.Doze模式
1.進入Doze模式
在手機未充電,完全靜止且熄屏一段時間後,Android系統會自動進入Doze模式
2.Doze模式效果
1.網絡通路被挂起
2.Wake Locks被無視
3.AlarmManager被推遲到下一個maintenance window視窗,
除非使用AlarmManager新方法: setAndAllowWhileIdle(),setExactAndAllowWhileIdle(),setAlarmClock()
4.WiFi掃描被停止
5.SyncAdapter同步工作被停止
6.JobScheduler定時任務被停止
Doze模式的五種狀态
ACTIVE: 活動狀态
INACTIVE: 螢幕關閉進入非活動狀态
IDLE_PENDING: 每隔30分鐘讓App進入預備狀态
IDLE: 空閑狀态
IDLE_MAINTENANCE:處理挂起任務
系統進入Doze模式後,每隔一段時間(30分鐘)會有一小段時間(30s)供APP處理被挂起任務,
但随着時間推移,間隔時間會變長,以此減少電量消耗
3.退出Doze模式
1.手機充電
2.手機移動
3.手機螢幕打開
2.App Standby模式
1.進入App Standby模式
長時間未被使用者使用的App,将進入App Standby狀态(被标志為空閑狀态)
2.退出App Standby模式
1.使用者主動啟動該App
2.該App有前台程序(前台activity/前台service),被其它前台程序啟動
3.該App在鎖屏或通知欄有可見的Notification
4.Android裝置充電時,會将所有Standby狀态的App釋放,處理挂起任務
5.如果App空閑時間很長,系統将允許App一天一次通路網絡
3.App Standby和Doze差別
App Standby不需要螢幕關閉,App進入背景一段時間,網絡也會受到限制
Doze模式需要螢幕關閉(通常晚上睡覺或長時間螢幕關閉才會進入)
3.阻止電池優化(白名單)
Android6.0及更高版本提供電池優化白名單,App加入白名單可逃脫Doze和App Standby限制,
處于白名單中的App也會受到一定限制: Jobs和Syncs以及正常Alarms也會被推遲;
使用者手動設定App進入白名單: 設定>電池>電池優化白名單
App檢測是否在白名單: PowerManager.isIgnoringBatteryOptimizations()
App請求加入白名單:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (pm != null && !pm.isIgnoringBatteryOptimizations(getPackageName())) {
//1.進入系統電池優化設定界面,把目前APP加入白名單
//startActivity(new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS));
//2.彈出系統對話框,把目前APP加入白名單(無需進入設定界面)
//在manifest添權重限 <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
}
二.AlarmManager定時鬧鐘失效
1.App被Kill後,AlarmManager失效(隻有App程序在運作時,才會收到系統定時AlarmManager通知)
添加守護程序,互相監聽重新開機; 提醒使用者加入鎖屏清理白名單
2.手機重新開機,AlarmManager任務失效
監聽重新開機廣播,重新設定定時鬧鐘
3.從Android4.4(API19)開始,AlarmManager機制修改,set(),setRepeating()定時不再精确,甚至setRepeating隻生效一次(不會重複)
新增精确定時方法: setExact(),setWindow(),setAlarmClock(),
4.從Android6.0(API23)開始,進入Doze模式(省電優化),AlarmManager被延緩
新增精确定時方法: setAndAllowWhileIdle(),setExactAndAllowWhileIdle()
從Android4.4(API19)開始,新增精準定時方法都是一次性鬧鐘,沒有重複定時的方法,
是以當需要重複周期鬧鐘,隻能在下一次喚醒時重新設定定時,間接實作重複鬧鐘!
精确定時一次Demo如下:
void setWakeAtTime(Context cxt, int delay) {
PendingIntent pi = PendingIntent.getService(cxt,0,new Intent(cxt, xxService.class),PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarm = (AlarmManager) cxt.getSystemService(Context.ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) //Android 6,針對省電優化
alarm.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + delay, pi);
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) //Android 4.4,針對set不準确
alarm.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + delay, pi);
else
alarm.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + delay, pi);
}
簡書: http://www.jianshu.com/p/585ca251b871
CSDN部落格: http://blog.csdn.net/qq_32115439/article/details/78848386
GitHub部落格: http://lioil.win/2017/12/19/Android-Alarm_Doze_Standby.html
Coding部落格: http://c.lioil.win/2017/12/19/Android-Alarm_Doze_Standby.html