一、前言
最近在看關(guān)于插件化的知識(shí),遇到了如何實(shí)現(xiàn)Service插件化的問(wèn)題,因此,先學(xué)習(xí)一下Service內(nèi)部的實(shí)現(xiàn)原理,這里面會(huì)涉及到應(yīng)用進(jìn)程和ActivityManagerService的通信,建議大家先閱讀一下之前的這篇文章 Framework 源碼解析知識(shí)梳理(1) - 應(yīng)用進(jìn)程與 AMS 的通信實(shí)現(xiàn),整個(gè)Service的啟動(dòng)過(guò)程離不開(kāi)和AMS的通信,從整個(gè)宏觀上來(lái)看,它的模型如下,是不是和我們之前分析的通信過(guò)程一模一樣:

二、源碼分析
當(dāng)我們?cè)?code>Activity/Service/Application中,通過(guò)下面這個(gè)方法啟動(dòng)Service時(shí):
public ComponentName startService(Intent service)
與之前分析過(guò)的很多源碼類(lèi)似,最終會(huì)調(diào)用到ContextImpl的同名方法當(dāng)中,而該方法又會(huì)調(diào)用內(nèi)部的startServiceCommon(Intent, UserHandle):

在該方法中,主要做了兩件事:
- 校驗(yàn)
Intent的合法性,對(duì)于Android 5.0以后,我們要求Intent中需要制定Package和Component中至少一個(gè),否則會(huì)拋出異常。 - 通過(guò)
Binder通信調(diào)用到ActivityManagerService的對(duì)應(yīng)方法,關(guān)于調(diào)用的詳細(xì)過(guò)程可以參考 Framework 源碼解析知識(shí)梳理(1) - 應(yīng)用進(jìn)程與 AMS 的通信實(shí)現(xiàn) 中對(duì)于應(yīng)用進(jìn)程到ActivityManagerService的通信部分分析。
ActivityManagerService中的實(shí)現(xiàn)為:

這里面,通過(guò)
mServices變量來(lái)去實(shí)現(xiàn)Service的啟動(dòng),而mServices的類(lèi)型為ActiveServices,它是ActivityManagerService中負(fù)責(zé)處理Service相關(guān)業(yè)務(wù)的類(lèi),無(wú)論我們是通過(guò)start還是bind方式啟動(dòng)的Service,都是通過(guò)它來(lái)實(shí)現(xiàn)的,它也被稱(chēng)為“應(yīng)用服務(wù)”的管理類(lèi)。
從通過(guò)ActiveServices調(diào)用startServiceLocked,到Service真正被啟動(dòng)的過(guò)程如下圖所示,下面,我們就來(lái)一一分析每一個(gè)階段究竟做了什么:

我們首先來(lái)看入口函數(shù)startServiceLocked的內(nèi)部實(shí)現(xiàn):
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, String callingPackage, final int userId)
throws TransactionTooLargeException {
final boolean callerFg;
//caller是調(diào)用者進(jìn)程在AMS的遠(yuǎn)程代理對(duì)象,類(lèi)型為ApplicationThreadProxy。
if (caller != null) {
//獲得調(diào)用者的進(jìn)程信息。
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;
}
//通過(guò)傳遞的信息,解析出要啟動(dòng)的Service,封裝在ServiceLookupResult中。
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType, callingPackage,
callingPid, callingUid, userId, true, callerFg, false);
if (res == null) {
return null;
}
if (res.record == null) {
return new ComponentName("!", res.permission != null
? res.permission : "private to package");
}
//對(duì)于每個(gè)被啟動(dòng)的Service,它們?cè)贏MS端的數(shù)據(jù)結(jié)構(gòu)為ServiceRecord。
ServiceRecord r = res.record;
if (!mAm.mUserController.exists(r.userId)) {
Slog.w(TAG, "Trying to start service with non-existent user! " + r.userId);
return null;
}
//判斷是否允許啟動(dòng)該服務(wù)。
if (!r.startRequested) {
final long token = Binder.clearCallingIdentity();
try {
final int allowed = mAm.checkAllowBackgroundLocked(
r.appInfo.uid, r.packageName, callingPid, true);
if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
Slog.w(TAG, "Background start not allowed: service "
+ service + " to " + r.name.flattenToShortString()
+ " from pid=" + callingPid + " uid=" + callingUid
+ " pkg=" + callingPackage);
return null;
}
} finally {
Binder.restoreCallingIdentity(token);
}
}
//是否需要配置相應(yīng)的權(quán)限。
NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
callingUid, r.packageName, service, service.getFlags(), null, r.userId);
if (Build.PERMISSIONS_REVIEW_REQUIRED) {
if (!requestStartTargetPermissionsReviewIfNeededLocked(r, callingPackage,
callingUid, service, callerFg, userId)) {
return null;
}
}
//如果該Service正在等待被重新啟動(dòng),那么移除它。
if (unscheduleServiceRestartLocked(r, callingUid, false)) {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "START SERVICE WHILE RESTART PENDING: " + r);
}
//給ServiceRecord添加必要的信息。
r.lastActivity = SystemClock.uptimeMillis();
r.startRequested = true;
r.delayedStop = false;
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
service, neededGrants));
//其它的一些邏輯,與第一次啟動(dòng)無(wú)關(guān),就先不分析了。
return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}
簡(jiǎn)單地來(lái)說(shuō),就是根據(jù)Intent查找需要啟動(dòng)的Service,封裝成ServiceRecord對(duì)象,初始化其中的關(guān)鍵變量,在這一過(guò)程中,加入了一些必要的邏輯判斷,最終調(diào)用了startServiceInnerLocked方法。
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
//...
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
//...
return r.name;
}
這里面的邏輯我們先忽略掉一部分,只需要知道在正常情況下它會(huì)去調(diào)用bringUpServiceLocked來(lái)啟動(dòng)Service:
private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting) throws TransactionTooLargeException {
//如果該Service已經(jīng)啟動(dòng)。
if (r.app != null && r.app.thread != null) {
sendServiceArgsLocked(r, execInFg, false);
return null;
}
//如果正在等待被重新啟動(dòng),那么什么也不做。
if (!whileRestarting && r.restartDelay > 0) {
return null;
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing up " + r + " " + r.intent);
//清除等待被重新啟動(dòng)的狀態(tài)。
if (mRestartingServices.remove(r)) {
r.resetRestartCounter();
clearRestartingIfNeededLocked(r);
}
//因?yàn)槲覀凂R上就要啟動(dòng)該Service,因此去掉它的延時(shí)屬性。
if (r.delayed) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (bring up): " + r);
getServiceMap(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
//如果該Service所屬的用戶(hù)沒(méi)有啟動(dòng),那么調(diào)用 bringDownServiceLocked 方法。
if (mAm.mStartedUsers.get(r.userId) == null) {
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;
}
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;
ProcessRecord app;
//如果不是運(yùn)行在獨(dú)立的進(jìn)程。
if (!isolated) {
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
+ " app=" + app);
//如果該進(jìn)程已經(jīng)啟動(dòng),那么調(diào)用realStartServiceLocked方法。
if (app != null && app.thread != null) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
//在Service所屬進(jìn)程已經(jīng)啟動(dòng)的情況下調(diào)用的方法。
realStartServiceLocked(r, app, execInFg);
return null;
} catch (TransactionTooLargeException e) {
throw e;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortName, e);
}
}
} else {
app = r.isolatedProc;
}
//如果該Service所對(duì)應(yīng)的進(jìn)程沒(méi)有啟動(dòng),那么首先啟動(dòng)該進(jìn)程。
if (app == null) {
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;
}
}
//將該ServiceRecord加入到等待的集合當(dāng)中,等到新的進(jìn)程啟動(dòng)之后,再去啟動(dòng)它。
if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}
if (r.delayedStop) {
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;
}
bringUpServiceLocked的邏輯就比較復(fù)雜了,它會(huì)根據(jù)目標(biāo)Service及其所屬進(jìn)程的狀態(tài),走向不同的分支:
- 進(jìn)程已經(jīng)存在,并且目標(biāo)
Service已經(jīng)啟動(dòng):sendServiceArgsLocked - 進(jìn)程已經(jīng)存在,但是目標(biāo)
Service沒(méi)有啟動(dòng):realStartServiceLocked - 進(jìn)程不存在:
startProcessLocked,并且將ServiceRecord加入到mPendingServices中,等待進(jìn)程啟動(dòng)之后再去啟動(dòng)該Service。
下面,我們就來(lái)一起分析一下這三種情況。
2.1 進(jìn)程已經(jīng)存在,并且目標(biāo) Service 已經(jīng)啟動(dòng)
首先來(lái)當(dāng)進(jìn)程已經(jīng)存在,且目標(biāo)Service已經(jīng)啟動(dòng)時(shí)所調(diào)用的sendServiceArgsLocked方法:
private final void 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;
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);
} 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;
}
}
}
這里面最關(guān)鍵的就是調(diào)用了r.app.thread的scheduleServiceArgs方法,它其實(shí)就是Service所屬進(jìn)程的ApplicationThread對(duì)象在AMS端的一個(gè)遠(yuǎn)程代理對(duì)象,也就是ApplicationThreadProxy,通過(guò)binder通信,它最終會(huì)回調(diào)到Service所屬進(jìn)程的ApplicationThread的scheduleServiceArgs中:
private class ApplicationThread extends ApplicationThreadNative {
public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
int flags ,Intent args) {
ServiceArgsData s = new ServiceArgsData();
s.token = token;
s.taskRemoved = taskRemoved;
s.startId = startId;
s.flags = flags;
s.args = args;
sendMessage(H.SERVICE_ARGS, s);
}
}
sendMessage函數(shù)會(huì)通過(guò)ActivityThread內(nèi)部的mH對(duì)象發(fā)送消息到主線程當(dāng)中,mH實(shí)際上是一個(gè)Handler的子類(lèi),在它的handleMessage回調(diào)中,處理H.SERVICE_ARGS這條消息:

在
handleServiceArgs方法,就會(huì)從mServices去查找對(duì)應(yīng)的Service,調(diào)用我們熟悉的onStartCommand方法,至于Service對(duì)象是如何被加入到mServices中的,我們?cè)?code>2.2節(jié)中進(jìn)行分析。
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) {
//調(diào)用 onStartCommand 方法。
res = s.onStartCommand(data.args, data.flags, data.startId);
} else {
s.onTaskRemoved(data.args);
res = Service.START_TASK_REMOVED_COMPLETE;
}
QueuedWork.waitToFinish();
try {
//通知AMS啟動(dòng)完成。
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
} catch (RemoteException e) {
// nothing to do.
}
ensureJitEnabled();
} catch (Exception e) {
if (!mInstrumentation.onException(s, e)) {
throw new RuntimeException(
"Unable to start service " + s
+ " with " + data.args + ": " + e.toString(), e);
}
}
}
}
這里面,我們會(huì)取得onStartCommand的返回值,再通過(guò)Binder將該返回值傳回到AMS端,在AMS的mServices的serviceDoneExecutingLocked中,會(huì)根據(jù)該返回值來(lái)修改ServiceRecord的屬性,這也就是我們常說(shuō)的onStartCommand方法的返回值,會(huì)影響到該Services之后的一些行為的原因,關(guān)于這些返回值之間的差別,可以查看Service.java的注釋?zhuān)部梢圆榭淳W(wǎng)上的一些教程:

2.2 進(jìn)程已經(jīng)存在,但是 Service 沒(méi)有啟動(dòng)
下面,我們來(lái)看Service沒(méi)有啟動(dòng)的情況,這里會(huì)調(diào)用realStartServiceLocked方法:
private final void 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;
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
final boolean newService = app.services.add(r);
bumpServiceExecutingLocked(r, execInFg, "create");
//更新Service所在進(jìn)程的oom_adj值。
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.ensurePackageDexOpt(r.serviceInfo.packageName);
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
//通知應(yīng)用端創(chuàng)建Service對(duì)象。
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
r.postNotification();
created = true;
} catch (DeadObjectException e) {
Slog.w(TAG, "Application dead when creating service " + r);
mAm.appDiedLocked(app);
throw e;
} finally {
if (!created) {
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
if (newService) {
app.services.remove(r);
r.app = null;
}
if (!inDestroying) {
scheduleServiceRestartLocked(r, false);
}
}
}
//這里面會(huì)遍歷 ServiceRecord.bindings 列表,因?yàn)槲覀冞@里是用startService方式啟動(dòng)的,因此該列表為空,什么也不會(huì)調(diào)用。
requestServiceBindingsLocked(r, execInFg);
updateServiceClientActivitiesLocked(app, null, true);
if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
null, null));
}
//這個(gè)在第一種情況中分析過(guò)了,會(huì)調(diào)用 onStartCommand 方法。
sendServiceArgsLocked(r, execInFg, true);
if (r.delayed) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (new proc): " + r);
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) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
"Applying delayed stop (from start): " + r);
stopServiceLocked(r);
}
}
}
這段邏輯,有三個(gè)地方需要注意:
-
app.thread.scheduleCreateService:通過(guò)這里會(huì)在應(yīng)用進(jìn)程創(chuàng)建Service對(duì)象 -
requestServiceBindingsLocked:如果是通過(guò)bindService方式啟動(dòng)的,那么會(huì)去調(diào)用它的onBind方法。 -
sendServiceArgsLocked:正如2.1節(jié)中所分析,這里最終會(huì)觸發(fā)應(yīng)用進(jìn)程的Service的onStartCommand方法被調(diào)用。
第二點(diǎn)由于我們今天分析的是startService的方式,所以不用在意,而第三點(diǎn)我們之前已經(jīng)分析過(guò)了。所以我們主要關(guān)注app.thread.scheduleCreateService這一句,和2.1中的過(guò)程類(lèi)似,它會(huì)回調(diào)到H中的下面這個(gè)消息處理分支當(dāng)中:

具體的
handleCreateService的處理邏輯如下圖所示:
private void 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);
Service service = null;
try {
//根據(jù)Service的名字,動(dòng)態(tài)的加載該Service類(lèi)。
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
} 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);
//1.創(chuàng)建ContextImpl對(duì)象。
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
//2.將 Service 作為它的成員變量 mOuterContext 。
context.setOuterContext(service);
//3.創(chuàng)建Application對(duì)象,如果已經(jīng)創(chuàng)建那么直接返回,否則先調(diào)用Application的onCreate方法。
Application app = packageInfo.makeApplication(false, mInstrumentation);
//4.調(diào)用attach方法,將ContextImpl作為它的成員變量mBase。
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
//5.調(diào)用Service的onCreate方法。
service.onCreate();
//6.將該Service對(duì)象緩存起來(lái)。
mServices.put(data.token, service);
try {
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
// nothing to do.
}
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to create service " + data.info.name
+ ": " + e.toString(), e);
}
}
}
以上的邏輯分為以下幾個(gè)部分:
- 根據(jù)
Service的名字,通過(guò)ClassLoader加載該類(lèi),并生成一個(gè)Service實(shí)例。 - 創(chuàng)建一個(gè)新的
ContextImpl對(duì)象,并將第一步中創(chuàng)建的Service實(shí)例作為它的mOuterContext變量。 - 創(chuàng)建
Application對(duì)象,這里會(huì)先判斷當(dāng)前進(jìn)程所對(duì)應(yīng)的Application對(duì)象是否已經(jīng)創(chuàng)建,如果已經(jīng)創(chuàng)建,那么就直接返回,否則會(huì)先創(chuàng)建它,并依次調(diào)用它的attachBaseContext(Context context)和onCreate()方法。 - 調(diào)用
Service的attach方法,初始化成員變量。
- 調(diào)用
Service的onCreate()方法。 - 將該
Service通過(guò)token作為key,緩存在mServices列表當(dāng)中,之后Service生命周期的回調(diào),都依賴(lài)于該列表。
2.3 進(jìn)程不存在的情況
在這種情況下,Service自然也不會(huì)存在,我們會(huì)走到mAm.startProcessLocked的邏輯,這里會(huì)去啟動(dòng)Service所在的進(jìn)程,它究竟是怎么啟動(dòng)的我們先不去細(xì)看,只需要知道它是這個(gè)目的就可以了,此外,還需要注意的是它將該ServiceRecord加入到了mPendingServices中。
對(duì)于Service所在的進(jìn)程,它的入口函數(shù)為ActivityThread的main()方法,在main方法中,會(huì)創(chuàng)建一個(gè)ApplicationThread對(duì)象,并調(diào)用它的attach方法:

而在
attach方法中,會(huì)調(diào)用到AMS的attachApplication方法:
在
attachApplication方法中,又會(huì)去調(diào)用內(nèi)部的attachApplicationLocked:
這里面的邏輯比較長(zhǎng),我們只需要關(guān)注下面這句,我們又看到了熟悉的
mServices對(duì)象:
在
ActiveServices中的該方法中,就會(huì)去遍歷前面談到的mPendingServices列表,再依次調(diào)用realStartServiceLocked方法,至于這個(gè)方法做了什么,大家可以回到前面的2.2節(jié)去看,這里就不再重復(fù)分析了。
三、小結(jié)
以上就是startService的整個(gè)流程,bindService也是類(lèi)似一個(gè)調(diào)用過(guò)程,其過(guò)程并不復(fù)雜,本質(zhì)上還是 Framework 源碼解析知識(shí)梳理(1) - 應(yīng)用進(jìn)程與 AMS 的通信實(shí)現(xiàn) 所談到的通信過(guò)程,我們所需要學(xué)習(xí)的是AMS端和Service所在的應(yīng)用進(jìn)程對(duì)于Service是如何管理的。
系統(tǒng)當(dāng)中的所有Service都是通過(guò)AMS的mServices變量,也就是ActiveServices類(lèi)來(lái)進(jìn)行管理的,并且每一個(gè)應(yīng)用進(jìn)程中的Service都會(huì)在AMS端會(huì)對(duì)應(yīng)一個(gè)ServiceRecord對(duì)象,ServiceRecord中維護(hù)了應(yīng)用進(jìn)程中的Service對(duì)象所需要的狀態(tài)信息。
并且,無(wú)論我們調(diào)用多少次startService方法,在應(yīng)用進(jìn)程側(cè)都會(huì)只存在一個(gè)Service的實(shí)例,它被存儲(chǔ)到ActivityThread的ArrayMap類(lèi)型的mServices變量當(dāng)中。
更多文章,歡迎訪問(wèn)我的 Android 知識(shí)梳理系列:
- Android 知識(shí)梳理目錄:http://www.itdecent.cn/p/fd82d18994ce
- 個(gè)人主頁(yè):http://lizejun.cn
- 個(gè)人知識(shí)總結(jié)目錄:http://lizejun.cn/categories/
