Job Scheduler

在應用開發中,有以下一些常見的耗電場景:

  • 經常爲了使一些特殊模塊正常工作,而通過喚醒 CPU 去執行對應程序,但 Google 測試發現,每次喚醒 CPU,即使程序只運行 1 秒鐘,但實際上消耗了大約兩分鐘的耗電量。
  • 一些並不重要的數據,在非 Wi-Fi 環境下上報,如上傳日誌等。
  • 在 CPU 高負荷狀態下去做一些數據清理工作。

以上這些操作在應用中是有必要的,但並不緊急,可以選擇在合適的環境下完成,因此Google 爲了提高電池的續航能力,在 Android 5.0(API 21)提供了一個 JobScheduler 組件,只有一系列的預置條件滿足時,才執行對應的操作,這樣既能省電,又保證了功能的完整性。也就是說可以將不緊急的任務交給 Job Scheduler 來處理,Job Scheduler 集中處理收到的任務,選擇合適的時間、合適的網絡,再一起進行執行。

在以下場景可以考慮使用 Job Scheduler:

  • 重要不緊急的任務,可以延遲執行,如定期數據庫數據更新和數據上報。
  • 耗電量較大的任務,比如充電時才希望執行的備份數據操作。
  • 不緊急可以不執行的網絡任務,如在 Wi-Fi 環境預加載數據。
  • 可以批量執行的任務。

使用 JobScheduler 主要兩個步驟,創建一個 JobScheduler 對象預設置任務執行條件以及創建 Job Service 執行具體的任務,接下來詳細介紹使用方法。

  • 創建 JobScheduler
    創建 JobScheduler,用來初始化一個 JobScheduler 以及設置觸發 JobScheduler 執行任務的條件。

1)通過 getSystemService()獲取一個 JobScheduler 的對象:
2)創建一個 JobInfo,描述一個任務的執行 ID,以及觸發這個任務的條件。

public class JobScheduleManager {
    private Context mContext;

    private JobScheduler jobScheduler;

    public JobScheduleManager(Context mContext) {
        this.mContext = mContext;
        jobScheduler = (JobScheduler) mContext.getSystemService(Context.JOB_SCHEDULER_SERVICE);
    }

    public boolean addJobScheduleTask(int taskId) {
        JobInfo.Builder builder = new JobInfo.Builder(taskId, new ComponentName(mContext.getPackageName(), JobScheduleService.class.getName()));
        switch (taskId) {
            case 1:
                builder.setPeriodic(1000);
                break;
            case 2:
                builder.setPersisted(false);
                break;
            default:
                break;
        }
        if (jobScheduler != null) {
            return this.jobScheduler.schedule(builder.build()) > 0;
        }
        return false;
    }

}

從代碼看到,首先通過 JobInfo 的 build 方法創建一個 JobInfo,有兩個參數,第一個參數 task_id 是任務 ID,這個 ID 有兩個作用:

  • 添加任務時,對不同的 ID 做不同的觸發條件,即用 switch 代碼實現。
  • 在執行時需要根據任務 ID 執行具體的任務。

第二個參數 ComponentName 是具體執行 JobSchedluer 任務的服務,參數爲進程包名以及服務類名。
在 switch 代碼段中,針對不同的任務設置不同的觸發條件,JobInfo 支持以下觸發條件:

在 switch 代碼段中,針對不同的任務設置不同的觸發條件,JobInfo 支持以下觸發條件:

  • setMinimumLatency(long minLatencyMillis):設置任務的延遲執行時間(單位是 ms),需要注意的是,setMinimumLatency 與 setPeriodic(long time)方法不兼容,同時調用這兩個方法會引起異常。
  • setOverrideDeadline(long maxExecutionDelayMillis):設置任務最晚的延遲時間。如果到了規定的時間,其他條件還未滿足,這個任務也會被啓動。與 setMinimumLatency (long time)一樣,setOverrideDeadline 與 setPeriodic(long time)同時調用會引發異常。
  • setPersisted(boolean isPersisted):設備重啓之後,任務是否還要繼續執行。
  • setRequiredNetworkType(int networkType):只有在滿足指定的網絡條件時,纔會被執行。共有三種類型:
  • JobInfo.NETWORK_TYPE_NONE:不管是否有網絡,這個任務都會被執行(如果未設置,這個參數就是默認參數)。
  • JobInfo.NETWORK_TYPE_ANY:只有在有網絡的情況下,任務纔可以執行,和網絡類型無關。
  • JobInfo.NETWORK_TYPE_UNMETERED:非運營商網絡(比如在 Wi-Fi 連接時),時任務纔會被執行。
  • setRequiresCharging(boolean requiresCharging):只有當設備在充電時,這個任務纔會被執行。
  • setRequiresDeviceIdle(boolean requiresDeviceIdle):只有當用戶沒有在使用該設備且有一段時間沒有使用時,纔會啓動該任務。

setRequiredNetworkType (int networkType)、setRequiresCharging (booleanrequireCharging)and setRequiresDeviceIdle(boolean requireIdle)這幾個方法可能會使任務無法執行,除非調用 setOverrideDeadline(long time)設置了最大延遲時間,使任務在爲滿足條件的情況下也會被執行。

這樣就完成添加一個任務到 JobScheduler 中。在添加一個任務時,要指定一個完成任務的 Service,JobSchedulerService,在任務條件觸發後,進入JobSchedulerService 執行具體的工作。接下來實現一個 JobService,也就是 JobSchedulerService。

public class JobScheduleService extends JobService {
    @Override
    public boolean onStartJob(JobParameters params) {
        // 具體執行的任務
        return false;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        // 取消一個任務
        return false;
    }
}

        <service
            android:name=".JobScheduleService"
            android:permission="android.permission.BIND_JOB_SERVICE">


        </service>

JobSchedulerService 類必須實現兩個方法 onStartJob(JobParameters params)和 onStopJob(JobParameters params)。

(1)onStartJob(JobParameters params)

任務開始時,執行 onStartJob(JobParameters params)方法,系統用來觸發已經被執行的 任 務 。 任 務 執 行 完 畢 , 需 要 調 用 jobFinished ( JobParameters params , booleanneedsRescheduled)來通知系統。

(2)void jobFinished(JobParameters params,boolean needsReschedule)

任務執行完後,調用 jobFinished 方法通知 JobScheduler。

(3)onStopJob(JobParameters params)

系統接收到一個取消請求時,調用 onStopJob(JobParameters params)方法取消正在等待執行的任務。如果系統在接收到一個取消請求時,實際任務隊列中已經沒有正在運行的任務,onStopJob(JobParameters params)不會被調用。

注意 JobService 運行在主線程,如果是耗時任務,一定要使用 ThreadHandler或者一個異步任務來運行耗時的操作,以防止阻塞主線程。

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