Android後臺排程任務與省電

Jacks Blog發表於2016-08-22

I. Handler:

在程式存活的期間有效使用, Google官方推薦使用。

  • 簡單易用。
  • 穩定高效。

II. AlarmManager:

利用系統層級的鬧鐘服務(持有Wake lock)。

如果需要精確的定時任務,這個是最佳選擇。

1. 功能

  • 在大概的時間間隔 執行/重複執行 指定任務。
  • 指定精確的時間間隔執行任務。

2. 特徵

  • 註冊以後,無論是自己的應用程式是否存在/元件是否存在,都會正常執行。
  • 所有註冊的鬧鐘服務都會在系統重啟後復位,因此如果需要保證任務,就需要註冊RECEIVE_BOOT_COMPLETE,保證重啟後,可以重新將任務註冊到鬧鐘服務中。
  • AlarmManager處理的是一個PendingIntent,因此通常是啟動一個服務,進行處理事務。

3. 備註

  • 官方不建議網路請求相關的使用AlarmManager。
  • 考慮到電量損耗,建議非特殊情況使用 大概時間的方式,這樣Android會盡量讓幾個任務打包在一起執行,防止頻繁的喚起手機。

III. Job Scheduler:

JobScheduler官方文件

建議網路相關任務放到Job Scheduler。

系統重啟以後,任務會依然保留在Job Scheduler當中。

只有在Api21或以上的系統支援

1. 優勢

  • 更節省電量
  • 更高效
  • 更易用

2. 明確的指定特定場景下執行(JobInfo):

由於是將多個任務打包在一個場景下執行,因此執行有略微的延後;並且有期限,如果在期限內還沒有滿足特定情況,系統會將這些任務加入佇列,並且隨後會進行執行。

  1. 裝置開始充電
  2. 空閒
  3. 連線上網路
  4. 斷開網路

3. 介面型別

boolean onStartJob(JobParams params) {
    // 開始執行
    // 注意這個方法是在主執行緒執行的,如果是耗時操作請拋到獨立執行緒中
    // jobFinished(JobParameters params) // 在完成任務並且決定是否還需要定時執行更多工
    // return 是否是在獨立現在還有事務要執行
}

void onStopJob(){
    // 用於清理資料,在結束任務後被回撥。
}

IV. GCM

GCM Netwrok Manager實際上在 Api 21 或以上也是使用了 Job Scheduler,在此之前的版本使用的是Google Play Service中實現Job Scheduler的功能。

GCMNetworkManager中有很多利於省點的規則。

1. 介面型別

  • 通過 OneoffTask.Builder()PeriodicTask.Builder()建立任務。
  • GcmTaskService#onRunTask(TaskParams params)是在後臺執行緒執行的。

觸發場景與JobInfo中的一樣。

V. Sync Adapter

Transferring Data Using Sync Adapters

  • 通常是用於同步較多的資料。
  • 也許這是Job Scheduler API 21前比較好的替代品。

同步服務端與本地裝置中的資料。

1. 特徵

  • 利於大資料同步。
  • 不需要依賴Google Play Service。
  • 省電穩定。
  • 使用者可以通過設定中主動檢視同步的時間,以及觸發同步,或者關閉同步。
  • API 7 或以上。

2. 備註

  • 可繫結一個賬戶。
  • 通過提供ContentProvider,並且與服務端同步的資料庫。
  • 只有在存在網路的時候才觸發同步。

2. 在一定的場景下觸發同步

儘可能的打包所有需要同步的任務在一個週期中執行,以此來進行儘可能的節省手機電量。

  • 服務端/裝置端資料發生變化。
  • 手機閒置時。
  • 一天。
  • 如果同步失敗,會放到同步失敗的佇列中,在儘可能的時候進行同步。

VI. Doze Mode

Deep Doze Mode

API 23中直接稱其為Doze Mode。

無論Target SDK是多少,只要裝置是Android API 23或以上會啟用該模式。

1. 特徵

  • 旨在: 在使用者離開裝置以後,儘可能的減少手機電量的消耗。
  • 開發人員並不需要做特殊的適配,但是會對上面提到的所有Schedule的方式(Job Scheduler、AlarmManager、Syncs Adapter)進行影響。

通過移動視窗打包任務請求,並且間隔時間會越來越久。

2. 進入條件

會同時滿足以下情況過後一段時間(大約30分鐘)以後生效:

  • 手機沒有在充電
  • 螢幕被關閉
  • 手機各方狀態保持穩定

退出條件是,進入條件中任意條件狀態發生變化。

3. 在兩個處理視窗之間的手機狀態

  1. 對所有應用拒絕網路訪問。
  2. 所有JobScheduler、Sync-Adapter、AlarmManager的任務都會被延後到視窗中執行。
  3. 系統會拒絕所有來自應用的WAKE-LOCK
  4. 停止所有Wifi以及GPS掃描
  5. 減少位置事件從裝置檢測WiFi熱點。

Light Doze Mode

API 24 或以上會啟用該模式

1. 特徵

  • 相比Deep Doze Mode,打包任務的頻率會更高些

2. 進入條件

會同事滿足以下情況後一段時間(大約幾分鐘)以後生效:

  • 手機沒有在充電
  • 螢幕被關閉
  • 處於穩定狀態/不穩定狀態

或者在以下的條件:

  • 處於Deep Doze Mode
  • 螢幕關閉
  • 手機沒有在充電
  • 手機不再處於穩定狀態

3. 退出條件

  • 螢幕開啟
  • 手機開始充電
  • 進入Deep Doze Mode

4. 在兩個處理視窗之間的手機狀態

  • 對所有應用拒絕網路訪問。
  • 所有JobScheduler與Sync-Adapter的任務都會被延後到視窗中執行。
  • 不會對AlarmManager中的任務進行影響,但是將無網路訪問(如果你的任務需要網路訪問,是時候改用JobScheduler或Sync-Adapter,保證在任務視窗執行會有網路)

中斷/避開Doze

以下所有情況,Google官方都建議不在特殊情景,不要去使用,由於中斷了省電的規則。

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. 白名單

白名單官方文件

官方建議可考慮加入白名單的情況

  • 主動請求加入白名單,使用者同一以後加入白名單;
  • 使用者也可以主動將App從白名單中刪除或新增應用;
  • 應用可以通過isIgnoringBatteryOptimizations()來獲知是否在白名單中;
  • 白名單的應用可以訪問網路與持有有效的WAKELOKE,但是其他Doze的約束依然存在(如延後的Job Scheduler、Syncs-Adapter、AlarmManager);

白名單的請求方式:

4. 特殊情況

前臺服務(foreground-service)將不會受到Doze模式影響。

Doze模式測試

Google官方提供了一些adb命令用於測試Doze模式,而非需要通過等待來進入Doze模式的。

1. 進入Doze模式

  • 準備一臺系統是在Android Nougat Devloper Preview4或以上版本的裝置。
  • 將其連線連線到電腦。
  • 通過 adb shell dumpsys battery unplug 命令讓裝置進入未連線充電的模式。
  • 通過 adb shell dumpsys deviceidle step [light|deep] 強行進入Doze模式。

退出Doze模式,讓手機恢復正常需要復位充電模式: adb shell dumpsys battery reset

2. 其他指令

  • 獲取裝置狀態 adb shell dumpsys deviceidle get [light|deep|force|screen|charging|network]

在Android Nougat Developer Preview 4中,Doze模式的狀態週期是:

Light: ACTIVE -> IDLE -> IDLE_MAINTENANCE -> OVERRIDE
Deep: ACTIVE -> IDLE_PENDING -> SENSING -> LOCATING -> IDLE -> IDLE_MAINTENANCE

© 2012 – 2016, Jacksgong(blog.dreamtobe.cn). Licensed under the Creative Commons Attribution-NonCommercial 3.0 license (This license lets others remix, tweak, and build upon a work non-commercially, and although their new works must also acknowledge the original author and be non-commercial, they don’t have to license their derivative works on the same terms). http://creativecommons.org/licenses/by-nc/3.0/

相關文章