JobScheduler之超時檢查

文中的源代碼版本爲api23java

JobScheduler之超時檢查

JobServiceContextJobService交互的過程當中會JobServiceContext會進行超時檢查,下面咱們來看看超時檢查是怎麼作的。 咱們須要解決的主要問題是:api

  1. 哪些操做會執行超時檢查
  2. 超時時間是多少
  3. 一旦發生超時JobServiceContext會怎麼處理

哪些操做會執行超時檢查

JobServiceContext中使用一個名爲scheduleOpTimeOut的方法來執行超時檢查,那麼哪些地方會調用該方法呢? 經過全局搜索發現有如下調用點:異步

  1. 執行服務的bind操做時
boolean executeRunnableJob(JobStatus job) {
    synchronized (mLock) {
        //...
        scheduleOpTimeOut();
        final Intent intent = new Intent().setComponent(job.getServiceComponent());
        boolean binding = mContext.bindServiceAsUser(intent, this,
                Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND,
                new UserHandle(job.getUserId()));
        //...
        return true;
    }
}
複製代碼
  1. 觸發JobService.onStartJob方法時
private void handleServiceBoundH() {
    //...
    try {
        mVerb = VERB_STARTING;
        scheduleOpTimeOut();
        service.startJob(mParams);
    } catch (RemoteException e) {
        Slog.e(TAG, "Error sending onStart message to '" +
                mRunningJob.getServiceComponent().getShortClassName() + "' ", e);
    }
}
複製代碼
  1. 等待JobService異步執行任務的期間
private void handleStartedH(boolean workOngoing) {
    switch (mVerb) {
        case VERB_STARTING:
            mVerb = VERB_EXECUTING;
            if (!workOngoing) {
                // Job is finished already so fast-forward to handleFinished.
                handleFinishedH(false);
                return;
            }
            //...
            //workOngoing爲true表示JobService
            //須要異步執行任務,完成任務後須要調用
            //jobFinished方法通知JSC
            scheduleOpTimeOut();
            break;
        default:
            //...
            return;
    }
}
複製代碼
  1. 中止JobService
private void sendStopMessageH() {
    removeOpTimeOut();
    //...
    try {
        mVerb = VERB_STOPPING;
        scheduleOpTimeOut();
        service.stopJob(mParams);
    } catch (RemoteException e) {
        //...
    }
}
複製代碼

能夠發現,JobService在執行每一步操做的時候都會有超時檢查。this

超時時間是多少

這個問題就須要咱們來看一下scheduleOpTimeOut方法了spa

private void scheduleOpTimeOut() {
    removeOpTimeOut();
    
    //有兩個事件
    final long timeoutMillis = (mVerb == VERB_EXECUTING) ?
            EXECUTING_TIMESLICE_MILLIS : OP_TIMEOUT_MILLIS;
    //log...
    Message m = mCallbackHandler.obtainMessage(MSG_TIMEOUT);
    mCallbackHandler.sendMessageDelayed(m, timeoutMillis);
    mTimeoutElapsed = SystemClock.elapsedRealtime() + timeoutMillis;
}
複製代碼

EXECUTING_TIMESLICE_MILLIS爲10分鐘,OP_TIMEOUT_MILLIS爲8秒 從代碼中咱們能夠發現超時時間有兩個,不一樣的操做有不一樣的超時時間 mVerbVERB_EXECUTING的超時消息,只有在JobService執行異步任務時纔會觸發,所以咱們能夠將超時簡單的分爲兩種:code

  1. JobService異步任務執行超時(10mins)
  2. 跨進程調用超時(8s)

一旦發生超時JobServiceContext會怎麼處理

JobServiceContext使用handleOpTimeoutH方法來處理超時進程

private void handleOpTimeoutH() {
    switch (mVerb) {
        case VERB_BINDING:
            //log...
            closeAndCleanupJobH(false /* needsReschedule */);
            break;
        case VERB_STARTING:
            //log...
            closeAndCleanupJobH(false /* needsReschedule */);
            break;
        case VERB_STOPPING:
            //log...
            closeAndCleanupJobH(true /* needsReschedule */);
            break;
        case VERB_EXECUTING:
            //log...
            sendStopMessageH();
            break;
        default:
            //log...
            closeAndCleanupJobH(false /* needsReschedule */);
    }
}
複製代碼

主要處理方法有closeAndCleanupJobHsendStopMessageH事件

  1. sendStopMessageH 該方法會馬上執行stopJob方法,通知JobService結束任務
  2. closeAndCleanupJobH 該方法會直接解綁JobService,咱們以前講過了此處再也不贅述。惟一一點是,若是是跨進程執行stopJob方法超時的話,那麼needsReschedule參數就爲true

總結

  1. JobScheduler在執行服務綁定、跨進程調用JobService.onStartJobJobService.onStopJob以及JobService異步執行任務期間都會進行超時檢查
  2. JobService異步執行超時時間爲10mins,其餘全部操做都是8s
  3. JobService異步執行超時後JobServiceContext會跨進程調用JobService.onStopJob。其餘操做超時,會調用closeAndCleanupJobH直接解綁服務,若是是跨進程調用JobService.onStopJob時超時,則還會從新執行Job.
相關文章
相關標籤/搜索