// 6
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®;
return msg;
}
…
}
…
return null;
}
注释1:从ServiceRecord中获取 processName赋值给 procName
注释2:根据 procName和Service的uid来传入到 AMS的 getProcessRecordLocked()
中,查询是否存在一个与Service对应的ProcessRecord类型对象。
如果不存在,则在注释5、6中调用 AMS的 startProcessLocked()
来创建一个引用程序进程。
如果存在,则在注释3、4中调用 realStartServiceLocked()
来启动一个Service。
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
…
try {
…
//1
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 {
…
}
…
}
这里也有一个Real方法。app.thread.scheduleCreateService
即调用调用主线程的 scheduleCreateService()
的方法。
我们知道 app.thread
就是 IApplicationThread
,通过AIDL,这时候的代码从 SystemServer进程到了 应用程序的进程中。
// ActivityThread.java
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);
}
这里创建了一个 CreateServiceData
类,把Service的信息都封装了进去,设置一个 H.CREATE_SERVICE
字段,sendMessage出去。
到了 ApplicationThread
这里,免不了要使用Handler来将线程切换到主线程去。我们直接来看看 H
是怎么处理这个信息的吧
// ActivityThread.java
public void handleMessage(Message msg) {
switch (msg.what) {
case CREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
//1
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
}
到了主线程中,调用 handleCreateService()
:
private void handleCreateService(CreateServiceData data) {
// 获取要启动S
ervice的应用程序的 LoadedApk
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
//1
service = (Service) cl.loadClass(data.info.name).newInstance();
} catch (Exception e) {
…
}
try {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
//创建上下文环境
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
//2
service.attach(context, this, data.info.na