JobScheduler是Android L版本新引入的API正蛙,JobScheduler,顧名思義塘幅,是用來調(diào)度工作昔案。工作被調(diào)度的條件包括網(wǎng)絡(luò)變化,充電插拔电媳,周期執(zhí)行等踏揣。使用場景包括wifi條件下數(shù)據(jù)下載上傳等等。谷歌為什么要引入這個新的API呢匾乓?是為了省電而制定的一種規(guī)范捞稿。想想如果每個開發(fā)者都利用這個API進行wifi網(wǎng)絡(luò)下數(shù)據(jù)上傳,數(shù)據(jù)上傳的操作將會被統(tǒng)一到同一個時間點,批量處理括享,這樣比許多應(yīng)用單獨喚醒要省電的多搂根。
下面展示一個小例子
主MainActivity
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED); 代表免費的網(wǎng)絡(luò),通常就是指wifi了
public class MainActivity extends Activity {
JobScheduler js;
JobInfo.Builder builder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
js=(JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
builder=new Builder(1, new ComponentName(this, DemoService.class));
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
js.schedule(builder.build());
}
}
需要被調(diào)度的Job
當(dāng)wifi可用時铃辖,這個DemoService 就會執(zhí)行onStartJob
public class DemoService extends JobService{
@Override
public boolean onStartJob(JobParameters params) {
// TODO Auto-generated method stub
final JobParameters mJobParameters=params;
AsyncTask<Void, Void, Void> mTask = new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
return null;
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
Toast.makeText(wenfengService.this, "hello", 1000).show();
jobFinished(mJobParameters, true);
super.onPostExecute(result);
}
};
mTask.execute();
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
// TODO Auto-generated method stub
Toast.makeText(this, "bye", 1000).show();
return true;
}
}
清單
<service
android:name=".DemoService "
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="true"/>
onStartJob函數(shù)常常有兩種場景
1.不耗時的操作剩愧,這時你應(yīng)該返回false
2.耗時的操作例如數(shù)據(jù)下載等,這是你應(yīng)該開啟一個新線程(因為JobService是跑在主線程的)娇斩,并且返回true
如果調(diào)度是任務(wù)執(zhí)行失敗了仁卷,怎么辦?
任務(wù)失敗的情況有很多犬第,例如下載失敗了锦积,例如下載過程wifi斷掉了。
沒問題歉嗓,google提供了方便的重新調(diào)度的方法丰介。
例如如果下載過程中,wifi斷掉了鉴分,JobService會回調(diào)onStopJob函數(shù)哮幢,這是只需要把函數(shù)的返回值設(shè)置為true就可以了。當(dāng)wifi重新連接后志珍,JobService會重新回調(diào)onStartJob函數(shù)橙垢。
而如果下載失敗了,例如上面的例子中的AsyncTask執(zhí)行失敗伦糯,怎么辦呢柜某?我們只需要在AsyncTask的onPostExecute中執(zhí)行jobFinished(mJobParameters, true),這里的true代表任務(wù)要在wifi條件重新滿足情況下重新調(diào)度敛纲。經(jīng)典的寫法如下喂击。
開始調(diào)度
@Override
public boolean onStartJob(final JobParameters params) {
mDownloadArtworkTask = new DownloadArtworkTask(this) {
@Override
protected void onPostExecute(Boolean success) {
jobFinished(params, !success);
}
};
mDownloadArtworkTask.execute();
return true;
}
停止調(diào)度
@Override
public boolean onStopJob(final JobParameters params) {
if (mDownloadArtworkTask != null) {
mDownloadArtworkTask.cancel(true);
}
return true;
}
如果調(diào)度的任務(wù)老是執(zhí)行失敗,怎么辦载慈?
為了省電的考慮惭等,失敗的任務(wù)在執(zhí)行條件滿足的情況下,要延時一段時間才能執(zhí)行办铡。而且隨著失敗次數(shù)的增多辞做,延時會越長。舉個例子寡具,因為wifi斷開而執(zhí)行失敗的任務(wù)秤茅,在wifi連上后不會馬上執(zhí)行,延時一段時間才能執(zhí)行童叠。
延時時間=30s*失敗次數(shù)框喳。
下圖是JobScheduler在framework層的時序圖课幕,下一章將用adb指令直觀查看JobScheduler的情況,不容錯過五垮。有問題可以留言喲乍惊,大家一起探討!