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.
相关文章
相关标签/搜索