概述
Service启动流程和Activity启动流程有些相似,不了解Activity启动流程的可以看我之前的一篇博客Android App启动过程
Start Service 流程
Context.startService()
首先我们先从 context.startService()
这个方法为起点进行分析,我们看下他的源码
## ContextWrapper.java
public class ContextWrapper extends Context {
public ComponentName startService(Intent service) {
return mBase.startService(service); //其中mBase为ContextImpl对象
}
}
这个方法又调用了ContextImpl.startService
## ContextImpl.java
class ContextImpl extends Context {
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, mUser);
}
private ComponentName startServiceCommon(Intent service, UserHandle user) {
try {
...
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver()), getOpPackageName(), user.getIdentifier());
...
return cn;
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
}
我们看到最后调用了ActivityManagerNative.getDefault().startService
,其中ActivityManagerNative.getDefault()
就是ActivityManagerService
,这时就完成了从调用进程
到system_server进程
,其中是通过Binder
传输的信息
AMS.startService
下面我们看一下AMS到底做了什么
## ActivityManagerService.java
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, 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;
try {
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}
这个方法又调用了ActivityService#startServiceLocked
## ActivityService.java
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException {
···
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;
···
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
return cmp;
}
继续调用了ActivityService#startServiceInnerLocked
## ActivityService.java
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
···
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
if (error != null) {
return new ComponentName("!!", error);
}
···
return r.name;
}
继续调用了ActivityService#bringUpServiceLocked
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
···
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);
//如果Service进程存在
if (app != null && app.thread != null) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
//启动Service
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 a dead object exception was thrown -- fall through to
// restart the application.
}
}
//如果不存在此进程,则
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";
Slog.w(TAG, msg);
bringDownServiceLocked(r);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
return null;
}
这个方法主要做了俩件事
- 如果Service进程已经存在,则直接调用
realStartServiceLocked
- 如果Service进程不存在,则直接执行
startProcessLocked
方法创建进程,进过层层的调用,最终会调用到AMS.attachApplicationLocked
方法,然后执行realStartServiceLocked
方法
AMS.attachApplicationLocked
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
...
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
...
if (!badApp) {
try {
//寻找所有需要在该进程中运行的服务
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
badApp = true;
}
}
...
return true;
}
继续调用 AS.attachApplicationLocked
boolean attachApplicationLocked(ProcessRecord proc, String processName)
throws RemoteException {
boolean didSomething = false;
...
if (mPendingServices.size() > 0) {
ServiceRecord sr = null;
try {
for (int i=0; i<mPendingServices.size(); i++) {
sr = mPendingServices.get(i);
if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
|| !processName.equals(sr.processName))) {
continue;
}
mPendingServices.remove(i);
i--;
proc.addPackage(sr.appInfo.packageName, sr.appInfo.longVersionCode,
mAm.mProcessStats);
//启动Service
realStartServiceLocked(sr, proc, sr.createdFromFg);
didSomething = true;
...
}
}
这个方法调用了realStartServiceLocked
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
...
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
r.postNotification();
created = true;
...
}
这个方法内部调用了app.thread.scheduleCreateService
,而app.thread
是IApplicationThread
类型的,他的实现是ActivityThread
的内部类ApplicationThread
是一个Binder
,下面我们看一下ApplicationThread#scheduleCreateService
这个方法
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);
}
这个方法其实是发送了一个消息给Handler
,这个Handler
是ActivityThread
的内部类H
class H extends Handler {
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case CREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
}
最终调用了handleCreateService
方法
private void handleCreateService(CreateServiceData data) {
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
//获取类加载器
java.lang.ClassLoader cl = packageInfo.getClassLoader();
//加载Service实例
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);
}
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);
//初始化Service
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//调用Service的onCreate方法
service.onCreate();
mServices.put(data.token, service);
try {
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} 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);
}
}
}
到这里Service就启动完成了
总结
整个StartService
过程,从进程的角度看Service
的启动流程
ProcessA
进程采用Binder
形式向syster_server
进程发起startService
请求syster_server
进程收到请求后,向zygote
进程发送创建进程的请求zygote
进程fork
出新的进程,进出新进程的ActivityThread
的main
方法- 新进程通过
Binder
向syster_server
进程发起attachApplication
请求 syster_server
进程收到请求后,进过一系列的准备后,通过Binder
向新进程发送scheduleCreateService
请求- 新进程收到请求后,通过
Handler
发送CREATE_SERVICE
消息 - 主线程收到message,创建
Service
,并回调onCreate