APP開發實戰163-JobScheduler介紹

許多APP都需要定期執行某個或某幾項任務,如在聯網狀態下,每隔一段時間上傳日誌數據給服務器,或在手機處於Idle狀態時,定期清理手機的存儲空間等。

以往實現這樣的功能時,往往需要啓動一個定時器不斷的輪詢執行任務的條件是否滿足,如果滿足還需啓動定時器定期執行任務,這種機制的實現方式比較麻煩。

34.13.1 JobScheduler介紹

在Android5.0(API 21)中,Google提供了一個叫做JobScheduler的功能組件來處理這種場景;在JobScheduler功能類中,有一個JobService類,它是使用JobScheduler回調的入口點。

JobService類中包含以下幾個函數:

    voidjobFinished (JobParameters params, boolean needsReschedule)

這個函數是在任務完成之後被調用

params---這個參數是從onStartJob函數傳遞過來的

needsReschedule---如爲true,此任務只會被執行一次;false則會被反覆執行。

booleanonStartJob (JobParametersparams)

在JobService的子類中,必需重寫這個函數。

params---傳遞此任務的相關信息

返回值爲true,此service必須在一個單獨的子線程中處理工作;返回值爲false,此任務沒有工作要做。

    booleanonStopJob (JobParametersparams)

當系統確定必須停止運行任務時,會調用此函數;甚至會在調用jobFinished函數之前被調用。

如果在設定的時間,任務運行的條件不再滿足時,此函數就會被調用:如要求的是設備要連接WiFi,但在執行任務的時候,用戶把WiFi切換掉了;或者任務需要在Idle狀態下執行,但手機進入了非Idle狀態。

params---傳遞此任務的相關信息

返回值爲true時,告訴JobManager根據創建Job時的設置,是否重新安排此任務執行;返回值爲false時,退出Job。

不管返回值是什麼,Job都必須停止執行。

 

具體代碼如下:

private JobScheduler mJobScheduler;

 

//聲明Job的任務Id數值
public static final int MY_BACKGROUND_JOB = 0;

 

//初始化JobScheduler對象

public void initVariables() {

...
    mJobScheduler = (JobScheduler)getSystemService(Context.JOB_SCHEDULER_SERVICE );


}

 

 

//設置執行此任務需滿足的條件、間隔時間和關機重啓後是否繼續執行

public static void scheduleJob(Contextcontext) {
    JobScheduler js =
            (JobScheduler)context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
    JobInfo job = new JobInfo.Builder(
            MY_BACKGROUND_JOB,

           //在JobSchedulerService類中執行任務
            new ComponentName(context,JobSchedulerService.class))

//設置在聯網狀態下執行此任務
           .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)

//設置在設備處於Idle狀態時執行此任務
            .setRequiresDeviceIdle(true)

//設置在設備處於充電狀態時執行此任務
            .setRequiresCharging(true)

//設置任務的執行間隔時間爲10秒
            .setPeriodic(10*1000)

//設置設備關機重啓後,還是繼續按上述要求執行此任務
            .setPersisted(true)
            .build();
    js.schedule(job);
}

Google的官方文檔中描述是必須滿足執行任務的條件後,任務纔會被執行,實際驗證,即使條件不滿足,任務也會被執行,也就是如下代碼和上述代碼的實際執行結果一樣:

public static void scheduleJob(Contextcontext) {
    JobScheduler js =
            (JobScheduler)context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
    JobInfo job = new JobInfo.Builder(
            MY_BACKGROUND_JOB,
            new ComponentName(context,JobSchedulerService.class))

//設置任務的執行間隔時間爲10秒
            .setPeriodic(10*1000)

//設置設備關機重啓後,還是繼續按上述要求執行此任務
            .setPersisted(true)
            .build();
    js.schedule(job);
}

 

 

//取消Job

private void cancelJob(){
    mJobScheduler.cancelAll();
}

 

public class JobSchedulerService extendsJobService {

    public static final intMY_JOB_MESSAGE = 0;

    private Handler mJobHandler = newHandler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg ) {
            Toast.makeText(getApplicationContext(), "JobService task running",Toast.LENGTH_LONG).show();


            jobFinished( (JobParameters)msg.obj, false);
            return true;
        }
    } );

    @Override
    public booleanonStartJob(JobParameters params ) {
        mJobHandler.sendMessage(Message.obtain( mJobHandler, MY_JOB_MESSAGE, params ) );


        return false;
    }

    @Override
    public boolean onStopJob(JobParameters params ) {
        Toast.makeText(getApplicationContext(), "JobService task stop", Toast.LENGTH_SHORT).show();


       mJobHandler.removeMessages(MY_JOB_MESSAGE);
        return false;
    }

}

在AndroidManifest.xml中增加如下聲明:

<uses-permissionandroid:name="android.permission.RECEIVE_BOOT_COMPLETED" />

 

<serviceandroid:name=".service.JobSchedulerService"
   android:permission="android.permission.BIND_JOB_SERVICE" />

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章