前言
启动service有两种方式:startService和bindService。 这一篇先讲startService,读者如果只想看流程图,可以直接跳到总结。
1. ContextImpl
代码路径:frameworks\base\core\java\android\app\ContextImpl.java
1.1 startService
我们在调用startService的时候,实际是调用到ContextImpl的startService
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
1.2 startServiceCommon
startServiceCommon通过ActivityManager获取AMS的接口IActivityManager,将启动service请求发送给AMS
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
// 调用AMS的IActivityManager接口启动service
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
getOpPackageName(), getAttributionTag(), 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 ServiceStartNotAllowedException.newInstance(requireForeground,
"Not allowed to start service " + service + ": " + cn.getClassName());
}
}
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
2. ActivityManagerService
代码路径:frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java
2.1 startService
AMS 的startService 实现如下
final ActiveServices mServices;
@Override
public ComponentName startService(IApplicationThread caller, Intent service ...) throws TransactionTooLargeException {
synchronized(this) {
// 通过Binder获取调用方的进程id
final int callingPid = Binder.getCallingPid();
// 通过Binder获取调用方的uid
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res;
try {
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, callingFeatureId, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}
3. ActiveServices
代码路径:frameworks\base\services\core\java\com\android\server\am\ActiveServices.java
3.1 startServiceLocked
ComponentName startServiceLocked(IApplicationThread caller, Intent service ...) throws TransactionTooLargeException {
return startServiceLocked(caller, service ....);
}
3.2 startServiceLocked
ComponentName startServiceLocked(IApplicationThread caller, Intent service ...) throws TransactionTooLargeException {
....
// 如果客户端尝试启动/连接的是别名,那么我们需要返回
// 客户端的别名组件名称,而不是“目标”组件名称,
final ComponentName realResult = startServiceInnerLocked(r, service, callingUid, callingPid, fgRequired, callerFg, allowBackgroundActivityStarts, backgroundActivityStartsToken);
if (res.aliasComponent != null
&& !realResult.getPackageName().startsWith("!")
&& !realResult.getPackageName().startsWith("?")) {
return res.aliasComponent;
} else {
return realResult;
}
}
3.3 startServiceInnerLocked
内部有两个startServiceInnerLocked 的重载,这里只分析最后一个:
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r ...) throws TransactionTooLargeException {
final int uid = r.appInfo.uid;
final String packageName = r.name.getPackageName();
final String serviceName = r.name.getClassName();
mAm.mBatteryStatsService.noteServiceStartRunning(uid, packageName, serviceName);
// 准备启动service
String error = bringUpServiceLocked(r, service.getFlags(), callerFg,
false /* whileRestarting */,
false /* permissionsReviewRequired */

最低0.47元/天 解锁文章
537

被折叠的 条评论
为什么被折叠?



