privateComponentNamestartServiceCommon(Intentservice,UserHandleuser){try{validateServiceIntent(service);service.prepareToLeaveProcess();// 向 ActivityManagerService 发送请求启动 Service 组件ComponentNamecn=ActivityManagerNative.getDefault().startService(mMainThread.getApplicationThread(),service,service.resolveTypeIfNeeded(getContentResolver()),getOpPackageName(),user.getIdentifier());if(cn!=null){if(cn.getPackageName().equals("!")){thrownewSecurityException("Not allowed to start service "+service+" without permission "+cn.getClassName());}elseif(cn.getPackageName().equals("!!")){thrownewSecurityException("Unable to start service "+service+": "+cn.getClassName());}}returncn;}catch(RemoteExceptione){thrownewRuntimeException("Failure from system",e);}}
publicComponentNamestartService(IApplicationThreadcaller,Intentservice,StringresolvedType,StringcallingPackage,intuserId)throwsTransactionTooLargeException{enforceNotIsolatedCaller("startService");// Refuse possible leaked file descriptorsif(service!=null&&service.hasFileDescriptors()==true){thrownewIllegalArgumentException("File descriptors passed in Intent");}if(callingPackage==null){thrownewIllegalArgumentException("callingPackage cannot be null");}synchronized(this){finalintcallingPid=Binder.getCallingPid();finalintcallingUid=Binder.getCallingUid();finallongorigId=Binder.clearCallingIdentity();ComponentNameres=mServices.startServiceLocked(caller,service,resolvedType,callingPid,callingUid,callingPackage,userId);Binder.restoreCallingIdentity(origId);returnres;}}
ComponentNamestartServiceLocked(IApplicationThreadcaller,Intentservice,StringresolvedType,intcallingPid,intcallingUid,StringcallingPackage,intuserId)throwsTransactionTooLargeException{finalbooleancallerFg;if(caller!=null){finalProcessRecordcallerApp=mAm.getRecordForAppLocked(caller);if(callerApp==null){thrownewSecurityException("");// 省略字符串内容}callerFg=callerApp.setSchedGroup!=Process.THREAD_GROUP_BG_NONINTERACTIVE;}else{callerFg=true;}// 查找是否存在于 service 对应的 ServiceRecord 对象,没有则封装一个ServiceLookupResultres=retrieveServiceLocked(service,resolvedType,callingPackage,callingPid,callingUid,userId,true,callerFg);if(res==null){returnnull;}if(res.record==null){returnnewComponentName("!",res.permission!=null?res.permission:"private to package");}ServiceRecordr=res.record;if(!mAm.getUserManagerLocked().exists(r.userId)){// 用户是否存在检查Slog.d(TAG,"Trying to start service with non-existent user! "+r.userId);returnnull;}NeededUriGrantsneededGrants=mAm.checkGrantUriPermissionFromIntentLocked(callingUid,r.packageName,service,service.getFlags(),null,r.userId);if(unscheduleServiceRestartLocked(r,callingUid,false)){if(DEBUG_SERVICE)Slog.v(TAG_SERVICE,"START SERVICE WHILE RESTART PENDING: "+r);}r.lastActivity=SystemClock.uptimeMillis();r.startRequested=true;r.delayedStop=false;r.pendingStarts.add(newServiceRecord.StartItem(r,false,r.makeNextStartId(),service,neededGrants));finalServiceMapsmap=getServiceMap(r.userId);booleanaddToStarting=false;if(!callerFg&&r.app==null&&mAm.mStartedUsers.get(r.userId)!=null){ProcessRecordproc=mAm.getProcessRecordLocked(r.processName,r.appInfo.uid,false);if(proc==null||proc.curProcState>ActivityManager.PROCESS_STATE_RECEIVER){if(r.delayed){// This service is already scheduled for a delayed start; just leave// it still waiting.returnr.name;}if(smap.mStartingBackground.size()>=mMaxStartingBackground){// Something else is starting, delay!smap.mDelayedStartList.add(r);r.delayed=true;returnr.name;}addToStarting=true;}elseif(proc.curProcState>=ActivityManager.PROCESS_STATE_SERVICE){addToStarting=true;}}returnstartServiceInnerLocked(smap,service,r,callerFg,addToStarting);}
privatefinalStringbringUpServiceLocked(ServiceRecordr,intintentFlags,booleanexecInFg,booleanwhileRestarting)throwsTransactionTooLargeException{if(r.app!=null&&r.app.thread!=null){// 满足条件,执行 service 的 onStartCommand 方法sendServiceArgsLocked(r,execInFg,false);returnnull;}if(!whileRestarting&&r.restartDelay>0){// If waiting for a restart, then do nothing.returnnull;}// We are now bringing the service up, so no longer in the// restarting state.if(mRestartingServices.remove(r)){r.resetRestartCounter();clearRestartingIfNeededLocked(r);}// Make sure this service is no longer considered delayed, we are starting it now.if(r.delayed){getServiceMap(r.userId).mDelayedStartList.remove(r);r.delayed=false;}// Make sure that the user who owns this service is started. If not,// we don't want to allow it to run.if(mAm.mStartedUsers.get(r.userId)==null){bringDownServiceLocked(r);returnmsg;}// Service is now being launched, its package can't be stopped.try{AppGlobals.getPackageManager().setPackageStoppedState(r.packageName,false,r.userId);}catch(RemoteExceptione){}catch(IllegalArgumentExceptione){}finalbooleanisolated=(r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS)!=0;finalStringprocName=r.processName;ProcessRecordapp;if(!isolated){app=mAm.getProcessRecordLocked(procName,r.appInfo.uid,false);if(app!=null&&app.thread!=null){try{app.addPackage(r.appInfo.packageName,r.appInfo.versionCode,mAm.mProcessStats);realStartServiceLocked(r,app,execInFg);returnnull;}catch(TransactionTooLargeExceptione){throwe;}catch(RemoteExceptione){Slog.w(TAG,"Exception when starting service "+r.shortName,e);}}}else{app=r.isolatedProc;}// Not running -- get it started, and enqueue this service record// to be executed when the app comes up.if(app==null){if((app=mAm.startProcessLocked(procName,r.appInfo,true,intentFlags,"service",r.name,false,isolated,false))==null){bringDownServiceLocked(r);returnmsg;}if(isolated){r.isolatedProc=app;}}if(!mPendingServices.contains(r)){mPendingServices.add(r);}if(r.delayedStop){// Oh and hey we've already been asked to stop!r.delayedStop=false;if(r.startRequested){stopServiceLocked(r);}}returnnull;}
// Find any services that should be running in this process...if(!badApp){try{// mServices 的类型为 ActivityServicesdidSomething|=mServices.attachApplicationLocked(app,processName);}catch(Exceptione){Slog.wtf(TAG,"Exception thrown starting services in "+app,e);badApp=true;}}
booleanattachApplicationLocked(ProcessRecordproc,StringprocessName)throwsRemoteException{booleandidSomething=false;// Collect any services that are waiting for this process to come up.if(mPendingServices.size()>0){ServiceRecordsr=null;try{for(inti=0;i<mPendingServices.size();i++){sr=mPendingServices.get(i);if(proc!=sr.isolatedProc&&(proc.uid!=sr.appInfo.uid||!processName.equals(sr.processName))){continue;}mPendingServices.remove(i);i--;proc.addPackage(sr.appInfo.packageName,sr.appInfo.versionCode,mAm.mProcessStats);realStartServiceLocked(sr,proc,sr.createdFromFg);didSomething=true;if(!isServiceNeeded(sr,false,false)){// 不需要的服务就丢弃bringDownServiceLocked(sr);}}}catch(RemoteExceptione){throwe;}}// Also, if there are any services that are waiting to restart and// would run in this process, now is a good time to start them. It would// be weird to bring up the process but arbitrarily not let the services// run at this point just because their restart time hasn't come up.if(mRestartingServices.size()>0){ServiceRecordsr;for(inti=0;i<mRestartingServices.size();i++){sr=mRestartingServices.get(i);if(proc!=sr.isolatedProc&&(proc.uid!=sr.appInfo.uid||!processName.equals(sr.processName))){continue;}mAm.mHandler.removeCallbacks(sr.restarter);mAm.mHandler.post(sr.restarter);}}returndidSomething;}
privatefinalvoidrealStartServiceLocked(ServiceRecordr,ProcessRecordapp,booleanexecInFg)throwsRemoteException{if(app.thread==null){thrownewRemoteException();}r.app=app;r.restartTime=r.lastActivity=SystemClock.uptimeMillis();finalbooleannewService=app.services.add(r);// 发送一个延时消息 SERVICE_TIMEOUT_MSG,Service 若没有启动超时,则回告诉 AMS 取消该消息bumpServiceExecutingLocked(r,execInFg,"create");mAm.updateLruProcessLocked(app,false,null);mAm.updateOomAdjLocked();booleancreated=false;try{if(LOG_SERVICE_START_STOP){StringnameTerm;intlastPeriod=r.shortName.lastIndexOf('.');nameTerm=lastPeriod>=0?r.shortName.substring(lastPeriod):r.shortName;EventLogTags.writeAmCreateService(r.userId,System.identityHashCode(r),nameTerm,r.app.uid,r.app.pid);}synchronized(r.stats.getBatteryStats()){r.stats.startLaunchedLocked();}mAm.ensurePackageDexOpt(r.serviceInfo.packageName);app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);// 进入 Service 的 onCreate app.thread.scheduleCreateService(r,r.serviceInfo,mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),app.repProcState);r.postNotification();created=true;}catch(DeadObjectExceptione){Slog.w(TAG,"Application dead when creating service "+r);mAm.appDiedLocked(app);// 创建服务时,应用挂了throwe;}finally{if(!created){// Keep the executeNesting count accurate.finalbooleaninDestroying=mDestroyingServices.contains(r);serviceDoneExecutingLocked(r,inDestroying,inDestroying);// Cleanup.if(newService){app.services.remove(r);r.app=null;}// Retry.if(!inDestroying){scheduleServiceRestartLocked(r,false);}}}requestServiceBindingsLocked(r,execInFg);updateServiceClientActivitiesLocked(app,null,true);// If the service is in the started state, and there are no// pending arguments, then fake up one so its onStartCommand() will// be called.if(r.startRequested&&r.callStart&&r.pendingStarts.size()==0){r.pendingStarts.add(newServiceRecord.StartItem(r,false,r.makeNextStartId(),null,null));}// 进入 Service 的 onStartCommand sendServiceArgsLocked(r,execInFg,true);if(r.delayed){getServiceMap(r.userId).mDelayedStartList.remove(r);r.delayed=false;}if(r.delayedStop){// Oh and hey we've already been asked to stop!r.delayedStop=false;if(r.startRequested){stopServiceLocked(r);}}}
在realStartServiceLocked方法内,首先会通过bumpServiceExecutingLocked方法,然后再调用scheduleServiceTimeoutLocked方法,向 ActivityManagerService 的 MainHandler类型的 mHandler 发送一个消息 SERVICE_TIMEOUT_MSG。若 Service 在启动过程中没有及时向 ActivityManagerService 返回消息,把SERVICE_TIMEOUT_MSG消息给取消掉,那么则认为 Service 启动超时了。
标记完了时间后,就通过scheduleCreateService方法来启动 Service ,让 Service 进去onCreate状态。
privatevoidhandleCreateService(CreateServiceDatadata){// If we are getting ready to gc after going to the background, well// we are back active so skip it.unscheduleGcIdler();LoadedApkpackageInfo=getPackageInfoNoCheck(data.info.applicationInfo,data.compatInfo);Serviceservice=null;try{java.lang.ClassLoadercl=packageInfo.getClassLoader();// 通过反射创建目标服务对象service=(Service)cl.loadClass(data.info.name).newInstance();}catch(Exceptione){}try{// 创建 ContextImplContextImplcontext=ContextImpl.createAppContext(this,packageInfo);context.setOuterContext(service);// 创建 Application 对象Applicationapp=packageInfo.makeApplication(false,mInstrumentation);service.attach(context,this,data.info.name,data.token,app,ActivityManagerNative.getDefault());// Service 进入 onCreate 状态service.onCreate();mServices.put(data.token,service);try{// 向 ActivityManagerService 发送消息取消 Service 启动延时消息ActivityManagerNative.getDefault().serviceDoneExecuting(data.token,SERVICE_DONE_EXECUTING_ANON,0,0);}catch(RemoteExceptione){// nothing to do.}}catch(Exceptione){}}
ActivityThread 类的handleCreateService主要是创建了 Service 对象,并且创建了ContextImpl对象和Application对象。同时调用了 Service 的onCreate方法。我们继承的 Service 的onCreate方法也是在这里被系统回调的。
随后向 ActivityManagerService 发送消息,取消 Service 延时启动的消息。
privatefinalvoidsendServiceArgsLocked(ServiceRecordr,booleanexecInFg,booleanoomAdjusted)throwsTransactionTooLargeException{finalintN=r.pendingStarts.size();if(N==0){return;}while(r.pendingStarts.size()>0){ExceptioncaughtException=null;ServiceRecord.StartItemsi;try{si=r.pendingStarts.remove(0);if(si.intent==null&&N>1){// If somehow we got a dummy null intent in the middle,// then skip it. DO NOT skip a null intent when it is// the only one in the list -- this is to support the// onStartCommand(null) case.continue;}si.deliveredTime=SystemClock.uptimeMillis();r.deliveredStarts.add(si);si.deliveryCount++;if(si.neededGrants!=null){mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,si.getUriPermissionsLocked());}// 添加延时处理,类似于 onCreate bumpServiceExecutingLocked(r,execInFg,"start");if(!oomAdjusted){oomAdjusted=true;mAm.updateOomAdjLocked(r.app);}intflags=0;if(si.deliveryCount>1){flags|=Service.START_FLAG_RETRY;}if(si.doneExecutingCount>0){flags|=Service.START_FLAG_REDELIVERY;}// 跨进程 Service 进入 onStartCommand 状态r.app.thread.scheduleServiceArgs(r,si.taskRemoved,si.id,flags,si.intent);}catch(TransactionTooLargeExceptione){}catch(RemoteExceptione){}catch(Exceptione){}}}