本文源代码基于 Android 7.0。
这篇文章来分析一下 startService() 的启动过程,相对于 startActivity() 要简单的多。
目录:
1. Context
/base/core/java/android/app/ContextImpl.java
启动服务调用的是 context.startService(),实现在 ContextImpl 类。
// 启动服务
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, mUser);
}
private ComponentName startServiceCommon(Intent service, UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), getOpPackageName(), user.getIdentifier());
// ...
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
还是会调用 ActivityManagerNative.getDefault().startService(),这个过程就不再分析了,最终会从发起端进程进入到 system server 进程,找到 ActivityManagerService。
2. system server 进程
/base/services/core/java/com/android/server/am/ActivityManagerService.java
// 启动Service
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, String callingPackage, int userId)
throws TransactionTooLargeException {
// ...
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);
Binder.restoreCallingIdentity(origId);
return res;
}
}
mServices 为 ActiveServices 类型。
/base/services/core/java/com/android/server/am/ActiveServices.java
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, String callingPackage, final int userId)
throws TransactionTooLargeException {
// ...
return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
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);
}
// ...
return r.name;
}
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
// ...
if (app != null && app.thread != null) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
realStartServiceLocked(r, app, execInFg);
return null;
} catch (TransactionTooLargeException e) {
throw e;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortName, e);
}
// ...
if (app == null && !permissionsReviewRequired) {
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;
}
}
// ...
return null;
}
最终会调用 bringUpServiceLocked(),当目标进程已存在,则直接执行 realStartServiceLocked()。
当目标进程不存在,则先执行 startProcessLocked() 创建进程, 经过层层调用 (这个具体过程可以看这篇文章:Framework篇 - 四大组件与进程启动的关系),最后会调用到 ActivityManagerService.attachApplicationLocked,然后再执行 realStartServiceLocked()。
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
if (app.thread == null) {
throw new RemoteException();
}
//...
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
// ...
}
会调用该目标进程 (Service 所在的进程) 的 ActivityThread.scheduleCreateService()。
3. 目标进程
/base/core/java/android/app/ActivityThread.java
public final class ActivityThread {
private class ApplicationThread extends ApplicationThreadNative {
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);
}
}
}
发送给 ActivityThread.H 对象 CREATE_SERVICE 消息。H 收到消息后,调用 handleCreateService():
private void handleCreateService(CreateServiceData data) {
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
// 反射创建 Service
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 {
// 创建 ContextImpl 对象
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
// 创建 Application 对象
Application app = packageInfo.makeApplication(false, mInstrumentation);
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
// 调用服务onCreate()方法
service.onCreate();
mServices.put(data.token, service);
try {
// 调用服务创建完成
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
}
}
4. 总结
到此,服务便正式启动完成。当创建的是本地服务或者服务所属进程已创建时,则无需经过上述步骤2、3,直接创建服务即可。