在目前的Application開發中,執行一些異步任務很是廣泛,其中有些任務的執行週期甚至超過了Application的生命週期,好比一些下載數據的任務或者一些更新網絡資源的任務。有時咱們須要執行一些非當即開始的任務。Android提供了一些能夠在applications中明智使用的API,用於 執行一些預期後臺任務。html
選擇一個合適執行方式能夠提升application 的性能,同時能夠節省設備的電量損耗。android
Android M引入了 Doze mode用於在用戶不使用手機一段時間後最大可能地節省電量。git
如下是幾個Android提供的API:github
Services容許在後臺長時間運行任務。可是在後臺執行Services相對來講比較耗電。bash
Services即便不執行什麼有效的任務,也會一直佔用設備的資源。當這些後臺Services監聽系統的廣播時會加劇以上的問題。網絡
在app運行期執行一些Schedule任務時,推薦使用Handler配合Timer和Thread。這比使用Alarm Manager, Job Scheduler等更簡單,也更高效。app
AlarmManager提供了系統級別alarm service的入口。它提供了在應用運行期外執行操做的方法。AlarmManager能夠在將來的某個時間啓動一個服務,它能夠在定時到達時觸發一個PendingIntent。異步
註冊後的alarm能夠在設備鎖屏時依然是保留的(任務能夠在設備鎖屏時觸發),可是在設備關閉或重啓以後就無效了。ide
AlarmManager 能夠在用於在特定時間觸發任務的操做,並不提供其餘更完善的執行條件:如設備空閒、網絡可用或者開始充電等條件。性能
示例:當咱們須要在一個小時後或者每一個小時執行一些操做時,AlarmManager是一個不錯的選擇。可是沒法在諸如網絡可用或者設備非充電狀態等狀態出現時觸發事件。
Job Scheduler 是全部提到的執行預期任務首選的方式,能夠高效地執行後臺任務。Job Scheduler API在Android 5.0(API 21)中引入的。
Job Scheduler運行在設備有可用資源或者合適的條件時觸發任務。在建立任務時能夠自定義各類條件。當知足生命的條件時,系統將在app的 JobService中執行定義的任務。Job Scheduler還能夠根據Doze模式和應用程序的待機限制執行必要的操做。
用這種方式執行任務,可讓設備長時間處於休眠狀態,從而延長電池使用時長。通常來講Job Scheduler能夠用來執行對時間要求不嚴格的全部任務。
GCM (Google Cloud Messaging)網絡管理擁有全部JobScheduler特性。GCM 網絡管理能夠用於高效執行全部重複或單次不緊急的任務,同時能夠有效的節省設備電量。
它用於後向兼容,能夠在Android 5.0如下使用。在API 23及以上GCM實際使用了系統的JobSchedule。GCM 網絡管理使用了Google Play services中的scheduling 引擎,所以只能在安裝了Google Play 的設備中使用。
谷歌強烈建議GCM的用戶升級到FCM,使用Firebase Job Dispatcher執行全部任務。
The Firebase JobDispatcher也是一個執行後臺任務的庫,它向後兼容(支持 API 21一下),能夠在API 9+上運行。
The Firebase JobDispatcher能夠運行在未安裝Google Play 的設備上。The Firebase JobDispatcher實際使用了AlarmManager,固然若是設備安裝了Google Play,則The Firebase JobDispatcher使用Google Play中的Scheduling 引擎。
Sync Adapter設計用來同步本地和雲端的數據。它只能夠用來執行這種任務。在本地或者雲端數據發生變化時能夠觸發數據同步,或者定時觸發。Android系統會嘗試使用批量同步從而節省電量,未傳輸的數據將在隊列中等待同步。系統只會在聯網狀況下嘗試進行數據同步。
固然,仍是建議儘量使用JobScheduler, Firebase JobDispatcher, or GCM Network Manager等方法。
介紹了這麼多,咱們來提供一個job scheduler的示例。
繼承JobService來建立JobSchedulerService:
public class JobSchedulerService extends JobService {
@Override
public boolean onStartJob(JobParameters params) {
return false;
}
@Override
public boolean onStopJob(JobParameters params) {
return false;
}
}複製代碼
JobService在main thread中執行,全部耗時邏輯應在異步線程中。
同時還須要在AndroidManifest中註冊JobScheduler:
<application>
<service
android:name=」.JobSchedulerService 「
android:permission=」android.permission.BIND_JOB_SERVICE」
android:exported=」true」/>
</application>複製代碼
建立JobInfo,以下所示須要傳遞 JobService。Job Builder容許建立job 執行的多個條件。
ComponentName serviceName = new ComponentName(context, JobSchedulerService.class);
JobInfo jobInfo = new JobInfo.Builder(JOB_ID, serviceName)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
.setRequiresDeviceIdle(true)
.setRequiresCharging(true)
.build();複製代碼
JobScheduler scheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
int result = scheduler.schedule(jobInfo);
if (result == JobScheduler.RESULT_SUCCESS) {
Log.d(TAG, 「Job scheduled successfully!」);
}複製代碼
能夠在這裏下載完整代碼:GitHub。
在執行預期任務,須要仔細考慮執行任務的時機,選擇合適的方式,考慮應用的運行性能和節電性能。
JobScheduler很是方便使用,同時即便在系統重啓後依然能夠執行。可是要注意JobScheduler要求API 21+。
歡迎閱讀,原文地址:android.jlelse.eu/schedule-ta…
歡迎關注公衆號wutongke,按期推送移動開發前沿技術文章: