Service的启动

以Android 8.0版本为基础,以启动运行在新进程的Service为场景,分析启动的流程,了解了Binder和AMS后会好理解些。

客户端进程向AMS发起启动Service请求

在Activity中调用startService()启动Service,但实际上Activity没有此方法,是其父类ContextWrapper实现的。

ContextWrapper.startService
1
2
3
public ComponentName startService(Intent service) {
return mBase.startService(service);
}

mBase:ContextImpl;
为什么是ContextImpl?
AT.performLaunchActivity()中,把创建好的ContextImpl传到Activity.attach()中,然后又传到attachBaseContext()中,最后赋给了ContextWrapper的mBase变量。

ContextImpl.startService
1
2
3
4
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
ContextImpl.startServiceCommon
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private ComponentName startServiceCommon(Intent service, boolean requireForeground, UserHandle user) {
try {
//验证Intent参数
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
//ActivityManager.getService()就是AMS在客户端进程的本地代理
ComponentName cn = ActivityManager.getService().startService(mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), requireForeground, getOpPackageName(), user.getIdentifier());
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());
} else if (cn.getPackageName().equals("?")) {
throw new IllegalStateException("Not allowed to start service " + service + ": " + cn.getClassName());
}
}
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}

经过Binder驱动,最终AMS.startService()被调用。

AMS处理Intent信息及一些情况
AMS.startService
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType,
boolean requireForeground, String callingPackage, int userId) throws TransactionTooLargeException {
enforceNotIsolatedCaller("startService");
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
if (callingPackage == null) {
throw new IllegalArgumentException("callingPackage cannot be null");
}
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res;
try {
res = mServices.startServiceLocked(caller, service, resolvedType, callingPid,
callingUid, requireForeground, callingPackage, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}

mServices:ActiveServices。
caller:客户端进程的IApplicationThread在AMS所在进程的本地代理,可间接调用客户端进程的ApplicationThread。

ActiveServices.startServiceLocked
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid,
int callingUid, boolean fgRequired, String callingPackage, final int userId) throws TransactionTooLargeException {
//发起调用的进程是否为前台应用
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=" + callingPid + ") when starting service " + service);
}
callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
} else {
callerFg = true;
}
//从ServiceMap中根据Intent查找缓存的ServiceRecord,如没有缓存则通过PMS检索Intent信息,包装成ServiceLookupResult然后返回
ServiceLookupResult res = retrieveServiceLocked(service, resolvedType, callingPackage,
callingPid, callingUid, userId, true, callerFg, false, false);
if (res == null) {
return null;
}
//启动失败,权限问题
if (res.record == null) {
return new ComponentName("!", res.permission != null ? res.permission : "private to package");
}
ServiceRecord r = res.record;

if (!mAm.mUserController.exists(r.userId)) {
return null;
}
//如果是间接启动Service(例如从PendingContent启动),则判断是否在后台状态下启动Service
final boolean bgLaunch = !mAm.isUidActiveLocked(r.appInfo.uid);
//如果有设置后台限制,将限制Service启动
boolean forcedStandby = false;
if (bgLaunch && appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) {
forcedStandby = true;
}
//fgRequired为false,forceSilentAbort也是false
boolean forceSilentAbort = false;
if (fgRequired) {
final int mode = mAm.mAppOpsService.checkOperation(AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName);
switch (mode) {
case AppOpsManager.MODE_ALLOWED:
case AppOpsManager.MODE_DEFAULT:
break;
case AppOpsManager.MODE_IGNORED:
fgRequired = false;
forceSilentAbort = true;
break;
default:
return new ComponentName("!!", "foreground not allowed as per app op");
}
}
//检查是否允许启动Service
if (forcedStandby || (!r.startRequested && !fgRequired)) {
final int allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName,
r.appInfo.targetSdkVersion, callingPid, false, false, forcedStandby);
if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
if (allowed == ActivityManager.APP_START_MODE_DELAYED || forceSilentAbort) {
return null;
}
if (forcedStandby) {
if (fgRequired) {
return null;
}
}
UidRecord uidRec = mAm.mActiveUids.get(r.appInfo.uid);
return new ComponentName("?", "app is in background uid " + uidRec);
}
}
//androd8.0版本以下,设置fgRequired保证其为false,
if (r.appInfo.targetSdkVersion < Build.VERSION_CODES.O && fgRequired) {
fgRequired = false;
}
...
r.lastActivity = SystemClock.uptimeMillis();
r.startRequested = true;
r.delayedStop = false;
r.fgRequired = fgRequired;
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),service, neededGrants, callingUid));
if (fgRequired) {
mAm.mAppOpsService.startOperation(AppOpsManager.getToken(mAm.mAppOpsService),
AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, true);
}
final ServiceMap smap = getServiceMapLocked(r.userId);
boolean addToStarting = false;
//处理延迟启动Service的情况,调用进程在前台,非前台Service
if (!callerFg && !fgRequired && r.app == null && mAm.mUserController.hasStartedUserState(r.userId)) {
ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
//proc.curProcState当前进程状态,值越大优先级越低
if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
//当前状态是延迟启动,直接返回
if (r.delayed) {
return r.name;
}
if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
smap.mDelayedStartList.add(r);
r.delayed = true;
return r.name;
}
addToStarting = true;
} else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
addToStarting = true;
}
}
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
return cmp;
}

处理Intent信息是否合法;
针对Service前台后台的情况判断是否可以启动;
设置ServiceRecord参数;
处理延迟启动Service。

ActiveServices.startServiceInnerLocked
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
ComponentName 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);
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() + mAm.mConstants.BG_START_TIMEOUT;
if (first) {
smap.rescheduleDelayedStartsLocked();
}
} else if (callerFg || r.fgRequired) {
smap.ensureNotStartingBackgroundLocked(r);
}
return r.name;
}
ActiveServices.bringUpServiceLocked
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting,
boolean permissionsReviewRequired) throws TransactionTooLargeException {
//Service所在进程存在,直接发起IPC调用Service的onStartCommand方法
if (r.app != null && r.app.thread != null) {
sendServiceArgsLocked(r, execInFg, false);
return null;
}
//Service正在重启,直接返回
if (!whileRestarting && mRestartingServices.contains(r)) {
return null;
}
//从重启列表中移除
if (mRestartingServices.remove(r)) {
clearRestartingIfNeededLocked(r);
}
//Service不再是延迟状态,重设重启等状态
if (r.delayed) {
getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
//Service所在用户未启动启动失败
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";
bringDownServiceLocked(r);
return msg;
}
try {
AppGlobals.getPackageManager().setPackageStoppedState(r.packageName, false, r.userId);
} catch (RemoteException e) {
} catch (IllegalArgumentException e) {
}

final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
final String procName = r.processName;
String hostingType = "service";
ProcessRecord app;

if (!isolated) {
//根据进程名和uid查找对应的ProcessRecord
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
if (app != null && app.thread != null) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
//如果ProcessRecord信息存在则启动Service
realStartServiceLocked(r, app, execInFg);
return null;
} catch (TransactionTooLargeException e) {
throw e;
} catch (RemoteException e) {
}
}
} else {
app = r.isolatedProc;
if (WebViewZygote.isMultiprocessEnabled()
&& r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
hostingType = "webview_service";
}
}
//查不到Service所在进程信息,调用AMS.startProcessLocked()启动新进程
if (app == null && !permissionsReviewRequired) {
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingType, 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";
bringDownServiceLocked(r);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
if (r.fgRequired) {
mAm.tempWhitelistUidLocked(r.appInfo.uid,SERVICE_START_FOREGROUND_TIMEOUT, "fg-service-launch");
}
//把ServiceRecord添加到待启动列表中,进程创建好之后会读取mPendingServices启动Service
if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}
//延迟启动被取消且Service已启动,则停止Service
if (r.delayedStop) {
r.delayedStop = false;
if (r.startRequested) {
stopServiceLocked(r);
}
}
return null;
}

如果ServiceRecord已经绑定了ProcessRecord,并且ProcessRecord绑定了客户端进程的IApplicationThread的本地代理,则直接回调Service的onStartCommand方法。

准备启动Service了,这里分为2种情况:

  • 首先判断进程如果存在,则直接调用ActiveServices.realStartServiceLocked()进行Service真正的启动;
  • 如果进程不存在,会先调用AMS.startProcessLocked()创建进程,然后把待启动的ServiceRecord添加到mPendingServices中。AMS通知Zygote进程fork出新的子进程,经过一系列的调用后回到AMS.attachApplicationLocked()方法中,然后调用ActiveServices.attachApplicationLocked()处理mPendingServices,判断uid和进程名相同时后调用ActiveServices.realStartServiceLocked()。后面的流程便和进程存在的情况相一致了。其中从AMS.startProcessLocked()AMS.attachApplicationLocked()和Activity启动流程第3部分是一样的,不再分析
    (点击查看)

然后往下看ActiveServices.realStartServiceLocked()

ActiveServices.realStartServiceLocked
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException {
if (app.thread == null) {
throw new RemoteException();
}
//ServiceRecord绑定进程信息
r.app = app;
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
//ProcessRecord保存一份ServiceRecord的引用
final boolean newService = app.services.add(r);
//发送一个创建Service超时的ANR消息
bumpServiceExecutingLocked(r, execInFg, "create");
mAm.updateLruProcessLocked(app, false, null);
updateServiceForegroundLocked(r.app, /* oomAdj= */ false);
mAm.updateOomAdjLocked();

boolean created = false;
try {
synchronized (r.stats.getBatteryStats()) {
r.stats.startLaunchedLocked();
}
mAm.notifyPackageUse(r.serviceInfo.packageName,PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
//一切准备完毕,向客户端发起IPC进行Service的创建
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
r.postNotification();
created = true;
} catch (DeadObjectException e) {
mAm.appDiedLocked(app);
throw e;
} finally {
if (!created) {
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
//请求AMS缓存的ProcessRecord
if (newService) {
app.services.remove(r);
r.app = null;
}
//如发生异常但Serive又不是主动销毁的再次重启Service
if (!inDestroying) {
scheduleServiceRestartLocked(r, false);
}
}
}
if (r.whitelistManager) {
app.whitelistManager = true;
}
requestServiceBindingsLocked(r, execInFg);
updateServiceClientActivitiesLocked(app, null, true);

//伪造一个StartItem以便于后面调用Service的onStartCommand方法
if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
null, null, 0));
}
//发起IPC回调客户端Service的onStartCommand方法
sendServiceArgsLocked(r, execInFg, true);
//重设重启等状态
if (r.delayed) {
getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
//延迟启动被取消且Service已启动,则停止Service
if (r.delayedStop) {
r.delayedStop = false;
if (r.startRequested) {
stopServiceLocked(r);
}
}
}
  • ServiceRecord和ProcessRecord相互绑定;
  • 发送一个创建Service超时的ANR消息;
  • 调用app.thread.scheduleCreateService()向客户端发起IPC进行Service的创建;
  • 调用sendServiceArgsLocked(),向客户端发起IPC回调Service的onStartCommand()方法。
发送Service创建超时的延时消息

调用bumpServiceExecutingLocked()发送一个延时消息,如果这个消息没有被移除,就会执行Service创建超时的流程,最终弹出ANR对话框;如果在超时之前执行完Service的
onCreate(),便会移除这个延时消息。

ActiveServices.bumpServiceExecutingLocked
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
boolean timeoutNeeded = true;
if ((mAm.mBootPhase < SystemService.PHASE_THIRD_PARTY_APPS_CAN_START)
&& (r.app != null) && (r.app.pid == android.os.Process.myPid())) {
timeoutNeeded = false;
}
long now = SystemClock.uptimeMillis();
if (r.executeNesting == 0) {
r.executeFg = fg;
ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now);
}
if (r.app != null) {
r.app.executingServices.add(r);
r.app.execServicesFg |= fg;
if (timeoutNeeded && r.app.executingServices.size() == 1) {
scheduleServiceTimeoutLocked(r.app);
}
}
} else if (r.app != null && fg && !r.app.execServicesFg) {
r.app.execServicesFg = true;
if (timeoutNeeded) {
scheduleServiceTimeoutLocked(r.app);
}
}
r.executeFg |= fg;
r.executeNesting++;
r.executingStart = now;
}
ActiveServices.scheduleServiceTimeoutLocked
1
2
3
4
5
6
7
8
void scheduleServiceTimeoutLocked(ProcessRecord proc) {
if (proc.executingServices.size() == 0 || proc.thread == null) {
return;
}
Message msg = mAm.mHandler.obtainMessage(ActivityManagerService.SERVICE_TIMEOUT_MSG);
msg.obj = proc;
mAm.mHandler.sendMessageDelayed(msg,proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
}

AMS的MainHandler发送一个延时的Service超时的消息,
SERVICE_TIMEOUT:前台服务超时时间20秒。
SERVICE_BACKGROUND_TIMEOUT:是前台服务的10倍,200秒。

向客户端发起IPC进行Service的创建

app.thread是Service所在进程的IApplicationThread在AMS的本地代理,经过Binder驱动,回到客户端进程,ApplicationThread.scheduleCreateService()被调用。

ApplicationThread.scheduleCreateService
1
2
3
4
5
6
7
8
public final void scheduleCreateService(IBinder token, ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
updateProcessState(processState, false);
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
s.compatInfo = compatInfo;
sendMessage(H.CREATE_SERVICE, s);
}

token:ServiceRecord是Binder类型,token是ServiceRecord在客户端进程的本地代理,用来映射客户端进程的Service和AMS进程的ServiceRecord。
构造CreateServiceData并发送给Hander,最终ActivityThread.handleCreateService()被调用。

ActivityThread.handleCreateService
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
private void handleCreateService(CreateServiceData data) {
unscheduleGcIdler();
LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
//LoadedApk使用AppComponentFactory.instantiateService()反射构造Service
service = packageInfo.getAppFactory().instantiateService(cl, data.info.name, data.intent);
} catch (Exception e) {
}
try {
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
//Service初始化并回调onCreate方法
service.attach(context, this, data.info.name, data.token, app, ActivityManager.getService());
service.onCreate();
//把Service缓存到ActivityThread
mServices.put(data.token, service);
try {
//通知AMS客户端进程Service的创建已完毕
ActivityManager.getService().serviceDoneExecuting(data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
}
}

LoadedApk使用AppComponentFactory.instantiateService()反射构造Service;
调用Service.attach()保存ActivityThread、ServiceRecord本地代理和AMS本地代理等到Service;
调用Service.onCreate方法,onCreate()只在第一次创建的时候被回调,后面只调用onStartCommand方法;
把ServiceRecord和Service缓存到ActivityThread;
通知AMS调用serviceDoneExecuting()方法。

AMS.serviceDoneExecuting
1
2
3
4
5
6
7
8
public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
synchronized(this) {
if (!(token instanceof ServiceRecord)) {
throw new IllegalArgumentException("Invalid service token");
}
mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
}
}
ActiveServices.serviceDoneExecutingLocked
1
2
3
4
5
6
7
8
void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
boolean inDestroying = mDestroyingServices.contains(r);
if (r != null) {
//处理onStartCommand()重启Service策略
...
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
}
}

调用serviceDoneExecutingLocked()方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying, boolean finishing) {
r.executeNesting--;
if (r.executeNesting <= 0) {
if (r.app != null) {
r.app.execServicesFg = false;
r.app.executingServices.remove(r);
if (r.app.executingServices.size() == 0) {
mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
}
...
}
...
}
}

移除了前面发送的Service创建超时ANR的延时消息。

回调Service的onStartCommand()方法

完成Service的创建之后,开始通知客户端进程回调Service的onStartCommand()方法。

ActiveServices.sendServiceArgsLocked
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
boolean oomAdjusted) throws TransactionTooLargeException {
final int N = r.pendingStarts.size();
if (N == 0) {
return;
}
ArrayList<ServiceStartArgs> args = new ArrayList<>();
while (r.pendingStarts.size() > 0) {
ServiceRecord.StartItem si = r.pendingStarts.remove(0);
if (si.intent == null && N > 1) {
continue;
}
si.deliveredTime = SystemClock.uptimeMillis();
r.deliveredStarts.add(si);
si.deliveryCount++;
if (si.neededGrants != null) {
mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants, si.getUriPermissionsLocked());
}
mAm.grantEphemeralAccessLocked(r.userId, si.intent, r.appInfo.uid, UserHandle.getAppId(si.callingId));
//发送Service启动超时的延时消息
bumpServiceExecutingLocked(r, execInFg, "start");
if (!oomAdjusted) {
oomAdjusted = true;
mAm.updateOomAdjLocked(r.app, true);
}
if (r.fgRequired && !r.fgWaiting) {
if (!r.isForeground) {
scheduleServiceForegroundTransitionTimeoutLocked(r);
} else {
r.fgRequired = false;
}
}
int flags = 0;
if (si.deliveryCount > 1) {
flags |= Service.START_FLAG_RETRY;
}
if (si.doneExecutingCount > 0) {
flags |= Service.START_FLAG_REDELIVERY;
}
args.add(new ServiceStartArgs(si.taskRemoved, si.id, flags, si.intent));
}

ParceledListSlice<ServiceStartArgs> slice = new ParceledListSlice<>(args);
slice.setInlineCountLimit(4);
Exception caughtException = null;
try {
//向客户端进程发起IPC,最终回调Service的`onStartCommand()`
r.app.thread.scheduleServiceArgs(r, slice);
} catch (TransactionTooLargeException e) {
caughtException = e;
} catch (RemoteException e) {
caughtException = e;
} catch (Exception e) {
caughtException = e;
}

if (caughtException != null) {
final boolean inDestroying = mDestroyingServices.contains(r);
for (int i = 0; i < args.size(); i++) {
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
}
if (caughtException instanceof TransactionTooLargeException) {
throw (TransactionTooLargeException)caughtException;
}
}
}

发送Service启动超时的延时消息。类似流程3,当客户端进程成功回调onStartCommand()后,会通知AMS调用serviceDoneExecuting()移除ANS延时消息.
调用sendServiceArgsLocked()回调Service的onStartCommand()方法。

客户端进程回调onStartCommand

经过Binder驱动,最终客户端进程的ApplicationThread.scheduleServiceArgs()被调用

ApplicationThread.scheduleServiceArgs
1
2
3
4
5
6
7
8
9
10
11
12
13
public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
List<ServiceStartArgs> list = args.getList();
for (int i = 0; i < list.size(); i++) {
ServiceStartArgs ssa = list.get(i);
ServiceArgsData s = new ServiceArgsData();
s.token = token;
s.taskRemoved = ssa.taskRemoved;
s.startId = ssa.startId;
s.flags = ssa.flags;
s.args = ssa.args;
sendMessage(H.SERVICE_ARGS, s);
}
}

token:ServiceRecord。
构造ServiceStartArgs并发送给Hander,最终ActivityThread.handleServiceArgs()被调用。

ActivityThread.handleServiceArgs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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);
} else {
s.onTaskRemoved(data.args);
res = Service.START_TASK_REMOVED_COMPLETE;
}
QueuedWork.waitToFinish();
try {
ActivityManager.getService().serviceDoneExecuting(data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
ensureJitEnabled();
} catch (Exception e) {
}
}
}

通过token取出缓存的Service,回调其onStartCommand()
跨进程调用AMS.serviceDoneExecuting(),根据onStartCommand()返回值处理Service被杀死后重启的逻辑,然后是移除Service启动超时ANR的消息(见4.2-4.4)。

总结
  • Service的创建依靠和AMS进程的交互,由AMS控制Service的合法性和权限,然后再通知客户端进程进行创建等操作。
  • Service的创建流程:
    • 进程A和AMS进程进行IPC,向AMS发送startService();
    • AMS进程收到请求后验证Intent信息,然后查询待启动Service所在进程是否启动,如果未启动则先通知Zygote进程创建待启动Service所在的进程B,并把Service添加到待启动Service列表中;
    • AMS进程通过Socket向Zygote进程通信,请求创建新进程,Zygote收到请求后fork子进程,当fork成功后子进程的ActivityThread的main方法被调用;
    • 回到进程B中,进程B和AMS进程进行IPC,向AMS发送attachApplication();
    • 回到AMS进程中,AMS查询待启动Service列表,调用ActiveServices.realStartServiceLocked()准备创建Service,前面如果待启动Service所在进程如果存在,则直接调用此方法;
    • AMS进程和进程B进程IPC,向进程B发送创建Service并回调其onCreate()、回调Service.onStartCommand()的命令;
    • 进程B接受请求,反射创建Service并回调onCreate()、onStartCommand(),Service创建并启动完成。
  • AMS在准备进行IPC调用进程B的onCreate()、onStartCommand()等之前均调用ActiveServices.bumpServiceExecutingLocked()发送一个延时的ANR的消息,当进程B完成onCreate()、onStartCommand()等之后,会再向AMS进程发起IPC调用AMS.serviceDoneExecuting()去移除那个延时的AND消息,如果时间到了进程B还未完成调用则会弹出ANR对话框。不要在onCreate()、onStartCommand()方法中做耗时任务,因为它们都运行在主线程
  • ANR超时时常SERVICE_TIMEOUT:前台服务超时时间20秒。SERVICE_BACKGROUND_TIMEOUT:是前台服务的10倍,200秒。
  • 关于AMS为Service创建新进程的形式和创建Activity当流程一致,均是和Zygote进程进行Socket通信,fork出子进程后再回到AMS进程继续Service的创建。