文中的源代碼版本爲api23java
JobServiceContext
與JobService
交互的過程當中會JobServiceContext
會進行超時檢查,下面咱們來看看超時檢查是怎麼作的。 咱們須要解決的主要問題是:api
JobServiceContext
會怎麼處理JobServiceContext
中使用一個名爲scheduleOpTimeOut
的方法來執行超時檢查,那麼哪些地方會調用該方法呢? 經過全局搜索發現有如下調用點:異步
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;
}
}
複製代碼
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);
}
}
複製代碼
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;
}
}
複製代碼
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秒 從代碼中咱們能夠發現超時時間有兩個,不一樣的操做有不一樣的超時時間 mVerb
爲VERB_EXECUTING
的超時消息,只有在JobService
執行異步任務時纔會觸發,所以咱們能夠將超時簡單的分爲兩種:code
JobService
異步任務執行超時(10mins)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 */);
}
}
複製代碼
主要處理方法有closeAndCleanupJobH
和sendStopMessageH
事件
sendStopMessageH
該方法會馬上執行stopJob
方法,通知JobService
結束任務closeAndCleanupJobH
該方法會直接解綁JobService
,咱們以前講過了此處再也不贅述。惟一一點是,若是是跨進程執行stopJob
方法超時的話,那麼needsReschedule
參數就爲true
。JobScheduler
在執行服務綁定、跨進程調用JobService.onStartJob
、JobService.onStopJob
以及JobService
異步執行任務期間都會進行超時檢查JobService
異步執行超時時間爲10mins,其餘全部操做都是8sJobService
異步執行超時後JobServiceContext
會跨進程調用JobService.onStopJob
。其餘操做超時,會調用closeAndCleanupJobH
直接解綁服務,若是是跨進程調用JobService.onStopJob
時超時,則還會從新執行Job
.