Service是Android系统四大组件之一,它主要被用来在后台处理一些耗时操作,也会被设计成对Client提供业务的服务模块。Activity组件主要用来和用户进行交互,Service组件则可以在后台处理用户触发的一些请求操作,然后直接在Activity中展现请求结果。Activity和Service组件结合使用,能让我们设计出模块更清晰的应用。
Service有两种启动方式,一种是Start方式;一种是Bind方式。两种方式的使用细节可以参照之前转载的Service官方文档。此次,我们就先分析start Service的系统流程,Binde Service的分析会在下一篇讲述。
start Service,实际调用的是ContextImpl::startService()函数:
@Override
public ComponentName ContextImpl::startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, mUser);
}
private ComponentName ContextImpl::startServiceCommon(Intent service, UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread()/*AMS可以通过该ApplicationThread的Binder对象跟当前的应用进程通信*/, service, service.resolveTypeIfNeeded(
getContentResolver()), getOpPackageName(), user.getIdentifier());//进入AMS::startService()
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException(
"Not allowed to start service " + service
+ " without permission " + cn.getClassName());
} else if (cn.getPackageName().equals("!!")) {
throw new SecurityException(
"Unable to start service " + service
+ ": " + cn.getClassName());
}
}
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
参数mMainThread指向启动该服务的应用进程,参数intent中一般会指定Service的class信息,或者服务的类型全限定名称。之后,实际调用AMS::startService(),返回值是启动的Service组件的名称。我们进入AMS分析:
@Override
public ComponentName AMS::startService(IApplicationThread caller, Intent service,
String resolvedType, String callingPackage, int userId)
throws TransactionTooLargeException {
enforceNotIsolatedCaller("startService");
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
if (callingPackage == null) {
throw new IllegalArgumentException("callingPackage cannot be null");
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"startService: " + service + " type=" + resolvedType);
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid, callingPackage, userId);//调用startServiceLocked()
Binder.restoreCallingIdentity(origId);
return res;
}
}
mService是AMS内部,类型为ActiveService的实例对象;它是AMS启动一个服务的辅助类,封装了很多启动Service的业务函数。收下判断传参的合法性,随后调用ActiveService::startServiceLocked():
ComponentName ActiveService::startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, String callingPackage, final int userId)
throws TransactionTooLargeException {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service
+ " type=" + resolvedType + " args=" + service.getExtras());
final boolean callerFg;
if (caller != null) {
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
if (callerApp == null) {
throw new SecurityException(
"Unable to find app for caller " + caller
+ " (pid=" + Binder.getCallingPid()
+ ") when starting service " + service);
}
callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
} else {
callerFg = true;
}
//ServiceRecord是AMS中描述一个Service组件的类型
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType, callingPackage,
callingPid, callingUid, userId, true, callerFg, false);//查找AMS中是否存在与参数service对应的ServiceRecord对象;如果不存在,则会通过PMS去获取与service对应的Service组件信息,并封装成ServiceLookupResult对象返回
if (res == null) {
return null;
}
if (res.record == null) {
return new ComponentName("!", res.permission != null
? res.permission : "private to package");
}
ServiceRecord r = res.record;
...
r.lastActivity = SystemClock.uptimeMillis();
r.startRequested = true;
r.delayedStop = false;
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
service, neededGrants));
final ServiceMap smap = getServiceMap(r.userId);
...
return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);//调用startServiceInnerLocked()去bring up一个Service
}
一个服务的启动必须由一个应用组件去触发,所以启动Service的应用组件进程是不能不存在的。接着根据参数,检查AMS中是否已经这个服务的信息,即是否已经启动过它;如果AMS不存在当前需要启动的Service组件的信息,则去PMS查询,因为PMS会扫描所有Apk中的组件,根据参数从PMS查询,就会得到当前需要启动的Service对应的ServiceRecord对象,随后将它封装成ServiceLookupResult对象返回。
ServiceRecord是AMS用于管理Service的类型,每一个启动的Service,在AMS中都以ServiceRecord对象描述;就如ActivityRecord一样。
随后调用ActiveService::startServiceInnerLocked():
ComponentName ActiveService::startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
}
r.callStart = false;
synchronized (r.stats.getBatteryStats()) {
r.stats.startRunningLocked();
}
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);//调用bringUpServiceLocked()去启动服务
if (error != null) {
return new ComponentName("!!", error);
}
if (r.startRequested && addToStarting) {
boolean first = smap.mStartingBackground.size() == 0;
smap.mStartingBackground.add(r);
r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
if (DEBUG_DELAYED_SERVICE) {
RuntimeException here = new RuntimeException("here");
here.fillInStackTrace();
Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r, here);
} else if (DEBUG_DELAYED_STARTS) {
Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r);
}
if (first) {
smap.rescheduleDelayedStarts();
}
} else if (callerFg) {
smap.ensureNotStartingBackground(r);
}
return r.name;
}
主要处理就是调用bringUpServiceLocked()函数去启动当前的服务:
private String ActiveService::bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
//Slog.i(TAG, "Bring up service:");
//r.dump(" ");
if (r.app != null && r.app.thread != null) {
sendServiceArgsLocked(r, execInFg, false);//如果该Service已经启动,则直接传递Service参数到进程的主线程中,此时会触发调用onStartCommand();此次Service启动已经完成
return null;
}
if (!whileRestarting && r.restartDelay > 0) {
// If waiting for a restart, then do nothing.
return null;
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing up " + r + " " + r.intent);
// 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) {
...
}
// Make sure that the user who owns this service is started. If not,
// we don't want to allow it to run.
if (!mAm.mUserController.hasStartedUserState(r.userId)) {
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": user " + r.userId + " is stopped";
Slog.w(TAG, msg);
bringDownServiceLocked(r);
return msg;
}
// Service is now being launched, its package can't be stopped.
try {
AppGlobals.getPackageManager().setPackageStoppedState(
r.packageName, false, r.userId);
} catch (RemoteException e) {
} catch (IllegalArgumentException e) {
Slog.w(TAG, "Failed trying to unstop package "
+ r.packageName + ": " + e);
}
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
final String procName = r.processName;//表示当前Service组件想要运行在其中的进程的名字
ProcessRecord app;
if (!isolated) {//isolated表示是否要求一个单独的进程来运行服务;TRUE为需要
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);//根据这个进程名字在AMS中查找该进程是否已经存在
if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
+ " app=" + app);
if (app != null && app.thread != null) {//如果进程已经启动,调用realStartServiceLocked()直接去启动Service
try {
app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
realStartServiceLocked(r, app, execInFg);//该service想运行的进程已经存在,此时直接去启动该Service即可
return null;
} catch (TransactionTooLargeException e) {
throw e;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortName, e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
} else {
// If this service runs in an isolated process, then each time
// we call startProcessLocked() we will get a new isolated
// process, starting another process if we are currently waiting
// for a previous process to come up. To deal with this, we store
// in the service any current isolated process it is running in or
// waiting to have come up.
app = r.isolatedProc;//得到运行Service的单独的进程,第一次为null
}
// Not running -- get it started, and enqueue this service record
// to be executed when the app comes up.
if (app == null && !permissionsReviewRequired) {//如果该服务想要运行的进程还没有启动,则调用startProcessLocked()先去启动进程,再去启动Service
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
"service", r.name, false, isolated, false)) == null) {
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": process is bad";
Slog.w(TAG, msg);
bringDownServiceLocked(r);
return msg;//进程启动失败,退出
}
if (isolated) {
r.isolatedProc = app;
}
}
if (!mPendingServices.contains(r)) {//将当前需要启动Service的ServcieRecord对象加入到mPendingServices
mPendingServices.add(r);
}
if (r.delayedStop) {
// Oh and hey we've already been asked to stop!
r.delayedStop = false;
if (r.startRequested) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
"Applying delayed stop (in bring up): " + r);
stopServiceLocked(r);
}
}
return null;
}
与Activity的启动类似,我们启动一个Service时,也需要判断当前Service是否已经启动过。结合Service的生命周期,如果该Service已经启动过,则直接去启动Service即可(即调用Service::onStartCommnad()函数),但Service::onCreate()不会被调用,因为onCreate()只在Service第一次创建时才会被调用;如果Service的宿主进程不存在,我们就先为该Service创建运行所需要的进程,然后再去启动它。为Service创建进程的流程与之前Activity启动时创建进程的过程基本一致,此处就不再分析。
我们假设此时我们是第一次启动该Service,此时需要为它创建进程。结合代码可知,在AMS发出了为Service创建进程的请求之后,会将当前的Service添加到mPendingServices集合中,它保存了所有需要去的Service的ServiceRecord对象。在进程创建完毕后,AMS就会遍历mPendingServices,去启动服务。
由Activity的启动过程分析可知,应用进程的入口函数是ActivityThread::main();应用进程启动完毕后,就会给AMS发送一个通知,告知AMS进程已经创建好了,可以去启动组件了。这个动作是在AMS::attachApplication(IApplicationThread)中处理的,参数是IApplicationThread类型;它用于AMS与当前应用进程的主线程交互。
集合之前分析Activity启动部分的内容,最终是在AMS::attachApplicationLocked(IApplicationThread, int)中处理:
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
// Find the application record that is being attached... either via
// the pid if we are running in multiple processes, or just pull the
// next app record if we are emulating process with anonymous threads.
ProcessRecord app;
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);//创建应用进程时,会将进程对象和pid保存到mPidsSelfLocked集合中,所以此时可以取出对应的进程对象
}
} else {
app = null;
}
...
// If this application record is still attached to a previous
// process, clean it up now.
if (app.thread != null) {//如果app中已经有线程,说明app以前存在,现在是重启;先清理掉这些信息
handleAppDiedLocked(app, true, true);
}
// Tell the process all about itself.
if (DEBUG_ALL) Slog.v(
TAG, "Binding process pid " + pid + " to record " + app);
final String processName = app.processName;
try {
AppDeathRecipient adr = new AppDeathRecipient(
app, pid, thread);//创建app死亡监听对象
thread.asBinder().linkToDeath(adr, 0);
app.deathRecipient = adr;
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
startProcessLocked(app, "link fail", processName);
return false;
}
EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
app.makeActive(thread, mProcessStats);//会将创建的ActivityThread对应的ApplicationThread对象的Binder实例保存到该ProcessRecord对象的thread成员中,用以和该进程的主线程交互
...
try {
...
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());//调用bindApplication()方法
updateLruProcessLocked(app, false, null);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
} catch (Exception e) {
// todo: Yikes! What should we do? For now we will try to
// start another process, but that could easily get us in
// an infinite loop of restarting processes...
Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
app.resetPackageList(mProcessStats);
app.unlinkDeathRecipient();
startProcessLocked(app, "bind fail", processName);
return false;
}
// Remove this record from the list of starting applications.
mPersistentStartingProcesses.remove(app);
if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
"Attach application locked removing on hold: " + app);
mProcessesOnHold.remove(app);
boolean badApp = false;
boolean didSomething = false;
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {//调用attachApplicationLocked(),去启动当前Activity组件堆栈最顶端的Activity
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
// Find any services that should be running in this process...
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);//检查mPendingServices中是否有Service组件需要在该新创建的进程中启动;在此之前,我们会把需要启动的Service组件添加到mPendingServices中
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
badApp = true;
}
}
...
return true;
}
与之前一样,先得到为当前Service启动而创建的新应用进程的ProcessRecord对象;调用ActivityThread::bindApplication()绑定应用信息,创建Instrumentation、LoadedApk和Application等对象。接着调用ActiveService::boolean attachApplicationLocked(ProcessRecord proc, String processName)启动服务:
boolean ActiveService::attachApplicationLocked(ProcessRecord proc, String processName)
throws RemoteException {
boolean didSomething = false;
// Collect any services that are waiting for this process to come up.
if (mPendingServices.size() > 0) {
ServiceRecord sr = null;
try {
for (int i=0; i 0) {
ServiceRecord sr;
for (int i=0; i
从mPendingServices中找到和当前进程匹配的ServiceRecord对象,即需要运行在当前新建进程的服务。调整mPendingServices集合,并调用ActiveService::realStartServiceLocked()去启动Service。除此之外,还会处理需要重启的Service。
分析ActiveService::realStartServiceLocked():
private final void ActiveService::realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
if (app.thread == null) {
throw new RemoteException();
}
if (DEBUG_MU)
Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
+ ", ProcessRecord.uid = " + app.uid);
r.app = app;//将Service运行的进程信息保存到对应的ServiceRecord对象中
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
final boolean newService = app.services.add(r);
bumpServiceExecutingLocked(r, execInFg, "create");
mAm.updateLruProcessLocked(app, false, null);
mAm.updateOomAdjLocked();
boolean created = false;
try {
if (LOG_SERVICE_START_STOP) {
String nameTerm;
int lastPeriod = 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.notifyPackageUse(r.serviceInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);//调用scheduleCreateService在服务进程中创建Service对象,它会发送CREATE_SERVICE消息,最终在该进程的ActivityThread中处理会触发调用onCreate()
r.postNotification();
created = true;
} catch (DeadObjectException e) {
Slog.w(TAG, "Application dead when creating service " + r);
mAm.appDiedLocked(app);
throw e;
} finally {
if (!created) {
// Keep the executeNesting count accurate.
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
// Cleanup.
if (newService) {
app.services.remove(r);
r.app = null;
}
// Retry.
if (!inDestroying) {
scheduleServiceRestartLocked(r, false);
}
}
}
if (r.whitelistManager) {
app.whitelistManager = true;
}
requestServiceBindingsLocked(r, execInFg);//处理bind service的情况:会将Service组件连接到请求绑定它的Activity中;内部会调用scheduleBindService()->handleBindService() -> onBind()被调用
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(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
null, null));
}
sendServiceArgsLocked(r, execInFg, true);//会触发调用Service::onStartCommand()
...
}
首先,调用ActivityThread::scheduleCreateService()函数去创建当前启动的Service;中间的Binder调用关系就不再描述,之前已有过类似分析。直接看它的处理:
private void ActivityThread::handleCreateService(CreateServiceData data) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);//得到进程中加载的应用程序,以LoadedApk描述
Service service = null;
try {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();//加载此时要启动的Service类,并创建其Servcie实例
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to instantiate service " + data.info.name
+ ": " + e.toString(), e);
}
}
try {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
//为该Service设置Context上下文环境
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);//创建一个Application对象,用来描述该Service所属的应用程序;
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());//将一些信息与该Service组件进行绑定
service.onCreate();//调用Service的onCreate()
mServices.put(data.token, service);//token指向AMS中管理Service的ServiceRecord对象,保存到mService集合中
try {
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);//通知AMS服务已经创建
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to create service " + data.info.name
+ ": " + e.toString(), e);
}
}
}
CreateServiceData封装了AMS传递的参数信息。首先,是去加载这个需要启动的Service。LoadedApk实例代表了一个被加载的应用信息,它与Application实例一样,都是在进程创建后的bindApplication()调用中被创建的;且进程内部,所有组件都共用这些对象。加载Service类之后,便会为Service设置当前Context信息;之后便将一些信息绑定到Service中,随后就会触发Service::onCreate()被调用,这时服务就已经创建完成,它的整个生命周期也就开始了。
再回到ActiveService::realStartServiceLocked()中,Service创建完毕后,start Service又会调用sendServiceArgsLocked()函数:
private final void ActiveService::sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
boolean oomAdjusted) throws TransactionTooLargeException {
final int N = r.pendingStarts.size();
if (N == 0) {
return;
}
while (r.pendingStarts.size() > 0) {
Exception caughtException = null;
ServiceRecord.StartItem si = null;
try {
si = r.pendingStarts.remove(0);
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Sending arguments to: "
+ r + " " + r.intent + " args=" + si.intent);
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());
}
bumpServiceExecutingLocked(r, execInFg, "start");
if (!oomAdjusted) {
oomAdjusted = true;
mAm.updateOomAdjLocked(r.app);
}
int flags = 0;
if (si.deliveryCount > 1) {
flags |= Service.START_FLAG_RETRY;
}
if (si.doneExecutingCount > 0) {
flags |= Service.START_FLAG_REDELIVERY;
}
r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);//最终会调用Service::onStartCommand()
} catch (TransactionTooLargeException e) {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Transaction too large: intent="
+ si.intent);
caughtException = e;
} catch (RemoteException e) {
// Remote process gone... we'll let the normal cleanup take care of this.
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while sending args: " + r);
caughtException = e;
} catch (Exception e) {
Slog.w(TAG, "Unexpected exception", e);
caughtException = e;
}
if (caughtException != null) {
// Keep nesting count correct
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
if (caughtException instanceof TransactionTooLargeException) {
throw (TransactionTooLargeException)caughtException;
}
break;
}
}
}
如果这次Service start过程有参数(如参数intent中会封装一些指令)需要投递,则会触发ActivityThread::scheduleServiceArgs()将参数投递到Service中,触发一些后台执行流程:
private void handleServiceArgs(ServiceArgsData data) {
Service s = mServices.get(data.token);
if (s != null) {
try {
if (data.args != null) {
data.args.setExtrasClassLoader(s.getClassLoader());
data.args.prepareToEnterProcess();
}
int res;
if (!data.taskRemoved) {
res = s.onStartCommand(data.args, data.flags, data.startId);//此处会调用Service::onStartCommand()函数
} else {
s.onTaskRemoved(data.args);
res = Service.START_TASK_REMOVED_COMPLETE;
}
QueuedWork.waitToFinish();
try {
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
ensureJitEnabled();
} catch (Exception e) {
if (!mInstrumentation.onException(s, e)) {
throw new RuntimeException(
"Unable to start service " + s
+ " with " + data.args + ": " + e.toString(), e);
}
}
}
}
ServiceArgsData封装了AMS传递的参数信息,我们的分析场景中不会牵扯到设置taskRemoved,所以这时就会触发调用Service::onStartCommand()调用,此时我们可以通过读取参数,来启动一些我们需要在该Service中执行的操作;至此,Service的有效生命周期就开始了。
回顾之前的分析,如果当时判断该Service已经启动过,即onCreate()已经调用过;则此时会直接调用sendServiceArgsLocked()函数,向Service中投递传入的参数,触发Service::onStartCommand()调用,而不会再去触发Service::onCreate()。这与我们所了解的Service的start生命周期是一致的。