相關閱讀:
吊炸天!74款APP完整源碼!
絕對乾貨-國內值得關注的官方API集合,很全很強大(必須收藏)
[乾貨]2017已來,最全面試總結——這些Android面試題你一定需要
來源:龔振傑
https://blog.dreamtobe.cn/2016/08/15/android_scheduler_and_battery/
I. Handler:
在進程存活的期間有效使用, Google官方推薦使用。
相關機制可以參見: Android Handler Looper機制
II. AlarmManager:
利用系統層級的鬧鐘服務(持有Wake Lock)。
1. 使用場景
在大概的時間間隔(重複)運行指定任務。
在精確的時間間隔(重複)運行指定任務。
2. 特徵
運行在系統的鬧鐘服務上的,註冊以後,無論是自己的應用進程或組件是否存在,都會正常運作。
所有註冊的鬧鐘服務都會在系統重啟後復位,因此如果需要保證任務,就需要註冊RECEIVE_BOOT_COMPLETE廣播,確保重啟後,可以重新將任務註冊到鬧鐘服務中。
AlarmManager處理的是一個PendingIntent。
考慮到電量損耗,建議非特殊情況使用大概時間間隔的規則,這樣Android會儘量讓幾個任務打包在一起執行,防止頻繁的喚起手機。
III. Job Scheduler:
JobScheduler官方文檔
1. 使用場景
在指定特定場景下執行指定任務
2. 特徵
Job Scheduler只有在Api21或以上的系統支持。
Job Scheduler是將多個任務打包在一個場景下執行。
在系統重啟以後,任務會依然保留在Job Scheduler當中,因此不需要監聽系統啟動狀態重複設定。
如果在一定期限內還沒有滿足特定執行所需情況,Job Scheduler會將這些任務加入隊列,並且隨後會進行執行。
3. 接口類型
boolean onStartJob(JobParams params) {
// 開始執行
// 注意這個方法是在主線程執行的,如果是耗時操作請拋到獨立線程中
// jobFinished(JobParameters params) // 在完成任務並且決定是否還需要定時執行更多任務
// return 是否是在獨立現在還有事務要執行
}
void onStopJob(){
// 用於清理數據,在結束任務後被回調。
}
IV. GCM(FCM)
GCM Network Manager實際上在 Api 21 或以上也是使用了 Job Scheduler,在此之前的版本使用的是Google Play Service中實現Job Scheduler的功能。
在GCMNetworkManager中有很多利於省電的規則。
在中國內地,該服務被牆,無法正常使用。
1. 使用場景
2. 特徵
系統級別維護的長連結,十分穩定。
3. 接口類型
V. Sync Adapter
Transferring Data Using Sync Adapters
1. 使用場景
用於同步服務端與本地設備中的數據。
2. 特徵
省電穩定。
可綁定一個帳戶。
利於大數據同步。
通過提供ContentProvider,可以快捷的與服務端同步的資料庫。
只有在存在網絡的時候才觸發同步。
不需要依賴Google Play Service。
用戶可以通過設置中主動查看同步的時間,以及觸發同步,或者關閉同步。
Sync Adapter在API7或以上就可以使用,因此在一些場景下這是Job Scheduler在API21之前比較好的替代品。
3. 在一定的場景下觸發同步
儘可能的打包所有需要同步的任務在一個周期中執行,以此來進行儘可能的節省手機電量。
VI. Doze Mode
Deep Doze Mode
API23中直接稱其為Doze Mode。
1. 特徵
旨在: 在用戶離開設備以後,儘可能的減少手機電量的消耗。
所有任務周期通過移動窗口打包任務執行,並且間隔時間會越來越久。
2. 進入條件
會同時滿足以下情況一段時間(大約30分鐘)以後生效:
退出條件是,進入條件中任意條件狀態發生變化。
3. 在兩個處理窗口之間的手機狀態
對所有應用拒絕網絡訪問。
所有JobScheduler、Sync-Adapter、AlarmManager的任務都會被延後到窗口中執行。
系統會拒絕所有來自應用的Wake Lock
停止所有Wifi以及GPS掃描
減少位置事件從設備檢測WiFi熱點。
Light Doze Mode
Android 7或以上會啟用該模式。
1. 特徵
2. 進入條件
會同時滿足以下情況一段時間(大約幾分鐘)以後生效:
或者在Deep Doze Mode的情況下同時滿足以下條件下生效:
3. 退出條件
屏幕打開
手機開始充電
進入Deep Doze Mode
4. 在兩個處理窗口之間的手機狀態
中斷/避開Doze
以下所有情況,Google官方都建議不在特殊情景,不要去使用,由於中斷了Doze Mode的省電規則。
1. AlarmManager
在精確的時間間隔中運行的任務: setAndAllowWhileIdle()、setExactAndAllowWhileIdle()。但是在非窗口期間並不解除無網絡訪問的限制,並且只有10s的時間給予處理。
指定鬧鐘事件AlarmManager.setAlarmClock()的事件會在鬧鐘結束前,令系統短暫的完全退出Doze模式,並且正常處理事件,系統為了突顯該鬧鐘事件,將會在系統的Status Bar上顯示物理鬧鐘的ICON。
2. FCM/GCM
(Firebase Cloud Messaging,舊版中稱為Google Cloud Messaging(GCM))。
FCM/GCM中高優先級的任務配置中("priority" : "high") 的消息,在Doze模式下可以正常及時到達。
3. 白名單
白名單官方文檔
官方建議可考慮加入白名單的情況
主動請求加入白名單,用戶同意以後才加入白名單;
用戶也可以主動將應用從白名單中刪除或將應用添加到白名單中;
應用可以通過isIgnoringBatteryOptimizations()來獲知是否在白名單中;
白名單的應用可以訪問網絡與持有有效的Wake Lock,但是其他Doze的約束依然存在(如延後的Job Scheduler、Syncs-Adapter、AlarmManager);
白名單的請求方式:
通過ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS打開電量優化頁面,用戶可以通過搜索來關閉應用的電量優化,以此加入白名單。
先持有REQUEST_IGNORE_BATTERY_OPTIMIZATIONS權限,然後通過啟動IntentACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS直接彈出Dialog讓用戶關閉應用的電量優化,以此加入白名單。
4. 特殊情況
前臺服務(Foreground Service)將不會受到Doze模式影響。
Doze模式測試
Google官方提供了一些adb命令用於測試Doze模式,而非需要通過等待來進入Doze模式的。
1. 進入Doze模式
準備一臺系統是在Android Nougat Developer Preview4或以上版本的設備。
將其連接連接到電腦。
通過執行adb shell dumpsys battery unplug命令讓設備進入未連接充電的模式。
通過執行adb shell dumpsys deviceidle step [light|deep]強行進入Doze模式。
退出Doze模式,讓手機恢復正常需要復位充電模式:adb shell dumpsys battery reset。
2. 其他指令
在Android Nougat Developer Preview 4中,Doze模式的狀態周期是:
Light: ACTIVE -> IDLE -> IDLE_MAINTENANCE -> OVERRIDE
Deep: ACTIVE -> IDLE_PENDING -> SENSING -> LOCATING -> IDLE -> IDLE_MAINTENANCE
Java和Android大牛頻道
歡迎關注我們,一起討論技術,掃描和長按下方的二維碼可快速關注我們。或搜索微信公眾號:JANiubility。
公眾號:JANiubility