文中的源代碼版本爲api23java
想一想看,若是一個應用程序須要執行一些後臺任務,你會怎麼實現? AlarmManager? Service? 又或者是SyncManager?android
今天咱們來學習另外一種解決方案:JobScheduler
。 JobScheduler
是在Android 5.0添加的,它能夠檢測網絡狀態、設備是否充電中、低電量、低存儲等狀態,當全部條件都知足時就會觸發執行對應的JobService
來完成任務。同時具有了重試、定時執行、持久化任務(設備重啓後可恢復任務)等功能。可謂是十分強大。 你們能夠查看該視頻或者該文章瞭解個大概。api
JobScheduler
的使用大體分爲三步網絡
JobService
類JobInfo
JobScheduler
系統服務執行任務JobScheduler
的原理大體是是經過監聽手機狀態,當條件知足時啓動Service
執行任務。 所以在使用JobScheduler
以前,咱們須要定義一個Service
,固然並非隨隨便便定義,而是須要派生自JobService
。 只須要重寫onStopJob
和onStartJob
便可。app
class DemoJobService: JobService() {
override fun onStartJob(params: JobParameters?): Boolean {
//do sth...
//這個返回值是有講究的
//true表示Service的工做在一個獨立線程中執行,工做完成以後須要調用jobFinish方法通知JobScheduler工做完成
//false表示Service的工做已經完成,JobScheduler收到通知以後會釋放資源
return false
}
//該方法會在一些極端場景下觸發
//好比當前的Job須要有Wifi鏈接的場景下才可執行,可是在執行期間
//用戶關閉Wifi,那麼就會觸發該方法
override fun onStopJob(params: JobParameters?): Boolean {
//do sth...
//true表示須要進行重試
//false表示再也不進行重試,Job將會被丟棄
return true
}
}
複製代碼
同時,在manifest
中註冊時,還須要設置一個權限(不然會報錯),以下ide
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme">
//...
<service android:name=".DemoJobService" android:permission="android.permission.BIND_JOB_SERVICE"/>
</application>
複製代碼
JobInfo
是對任務的描述,好比說須要監聽哪些狀態、重試策略、任務執行時間、是否持久化等等。 JobInfo.Builder
的構造函數須要傳入一個jobId
,是Job
的惟一標誌,後續經過該jobId
來取消Job
。 經過Builder
模式構造JobInfo
。函數
val jobInfo = JobInfo.Builder(1, ComponentName(packageName, DemoJobService::class.java.name))
.setBackoffCriteria(1000,JobInfo.BACKOFF_POLICY_LINEAR) //重試機制
.setMinimumLatency(1000)//設置延遲時間
.setOverrideDeadline(10000)//設置最後期限,若是達到該時間點,Job還沒被執行,那麼會強制執行一次
// .setPeriodic(2000)//每隔2s執行一次,跟上面兩個會衝突
.setPersisted(true)//持久化,就算手機關機,啓動以後也能夠恢復Job,須要RECEIVE_BOOT_COMPLETED權限
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)//設置Job依賴的網絡類型
.setRequiresCharging(false)//是否要求設備處於充電狀態
.setRequiresDeviceIdle(false)//是否要求設備處於空閒狀態
.build()
複製代碼
最後經過getSystemService
獲取JobScheduler
服務執行任務就能夠了學習
//執行任務
val jobScheduler = getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
jobScheduler.schedule(jobInfo)
//取消任務
jobScheduler.cancel(1)
複製代碼
JobScheduler
上手仍是比較簡單的,因爲本文是基於api23的源碼,所以還有不少新功能沒有在源碼中展現出來,如setRequiresBatteryNotLow
(設置Job
對電量的要求)、setRequiresStorageNotLow
(設置Job
對存儲空間的要求)等,你們有興趣能夠本身去了解一下。 後續,我會從源碼角度分析JobScheduler
的工做原理。ui