JobScheduler 和 JobService


使用AlarmManager、IntentService和PendingIntent相互配合,創走周期性的后台任務,實現一個完全可用的后台服務還需要手動執行以下操作。

  計划一個周期性任務

  檢查周期性任務的運行狀態

  檢查網絡是否可用

在實際場景下,還有更多想法需要實現,例如請求失敗,是否還需要稍后重試機制。或者是只允許應用使用不限量的網絡連接...

在系統控制方面,本章實現的后台服務也存在一些問題,它無法在某種情況停下來,除非手動停止。

 

 

JobScheduler:除了實現常規后台任務之外,JobScheduler還支持按場景、按條件運行后台服務。

 

JobScheduler的使用:

創建一個類繼承JobService,並覆蓋onStartJob(JobParameters parms)方法和onStopJob(JobParameters params)。

public class PollService extends JobService { @Override public boolean onStartJob(JobParameters params) { return false; } @Override public boolean onStopJob(JobParameters params) { return false; } }

Android准備好執行任務時,服務就會啟動,此時會在主線程上收到onStartJob()方法調用。該方法返回false結果表示:"交代的任務我已全力去做,現在做完了。”返回 true 結果則表示:“任務收到,正在做,但是還沒有做完。”

JobService在執行的時候需要單開線程,可以使用AsyncTask按如下方式創建新線程。

    private PollTask mCurrentTask; @Override public boolean onStartJob(JobParameters parms){ mCurrentTask = new PollTask(); mCurrentTask.execute(parms); return true; } private class PollTask extends AsyncTask<JobParameters,Void,Void> { @Override protected Void doInBackground(JobParameters... params) { JobParameters jobParams = params[0]; //執行任務的邏輯
        jobFinished(jobParams, false); return null; } }  

任務執行完畢后,就可以調用jobFinished(JobParameters, boolean)方法通知結果,如果該方法的第二個參數傳入true的話,就等於說:“事情這次做不完了,請計划在下次某個時間繼續吧。”

 

onStopJob(JobParameters)方法適合在中斷任務時調用,用戶通常需要服務在有WIFI連接時才運行,如果在調用JobFinished()之前(任務完成之前),手機就沒了Wifi,onStopJob(...) 方法就會被調用,也就是說,一切任務就立即停止了。

@Override
public boolean onStopJob(JobParameters params) {
    if (mCurrentTask != null) {
    mCurrentTask.cancel(true);
    }
    return true;
}

調用 onStopJob(...) 方法就是表明,服務馬上就要停掉了。不要抱有幻想,請立即停止手頭上的一切事情。這里,返回 true 表示:“任務應該計划在下次繼續。”返回 false 表示:“不管怎樣,事情就到此結束吧,不要計划下次了。”

 

使用JobService,必須在Manifest配置清單中添加權限:

<service
android:name=".PollService"
android:permission="android.permission.BIND_JOB_SERVICE"  //添加的權限控制只有JobScheduler才能運行它。
android:exported="true"/>

 

通過JobScheduler檢查是否已計划好了任務:

final int JOB_ID = 1;
JobScheduler scheduler = (JobScheduler)
    context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
boolean hasBeenScheduled = false;
for (JobInfo jobInfo : scheduler.getAllPendingJobs()) {
    if (jobInfo.getId() == JOB_ID) {
    hasBeenScheduled = true;
    }
}

 

PoolService的運行:

final int JOB_ID = 1;

JobScheduler scheduler = (JobScheduler)
    context.getSystemService(Context.JOB_SCHEDULER_SERVICE);

    JobInfo jobInfo = new JobInfo.Builder(JOB_ID, new ComponentName(context, PollService.class))
    .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
    .setPeriodic(1000 * 60 * 15)
    .setPersisted(true)
    .build();
scheduler.schedule(jobInfo);

上述代碼計划任務每15分鍾運行一次,但前提條件是有Wi-Fi或有可用的不限流量網絡。調用 setPersisted(true) 方法可保證服務在設備重啟后也能按計划運行。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM