在Service启动流程(startService)的最后,分析了在调用startService时可能存在的三种情况,本文分析第二种情况—Service与App在同一个进程,但未启动。
Service启动流程(startService)最后已经说明,在这种情况下,系统会执行realStartServiceLocked
函数。
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app) throws RemoteException {
......
r.app = app;
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
app.services.add(r);
bumpServiceExecutingLocked(r, "create");
updateLruProcessLocked(app, true, true);
boolean created = false;
try {
......
//跨进程去执行Service实例的创建
app.thread.scheduleCreateService(r, r.serviceInfo,
compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
r.postNotification();
created = true;
} finally {
if (!created) {
app.services.remove(r);
scheduleServiceRestartLocked(r, false);
}
}
......
//Service创建完成后,执行onStartCommand函数
sendServiceArgsLocked(r, true);
}
函数的逻辑还是比较清晰的,完成的工作主要有两个:
- 创建Service实例
- 执行onStartCommand方法
接下来就来看下这两个任务时如何完成的。
创建Service实例是一个Binder跨进程调用,Binder细节就不分析,直接进入ActivityThread查看scheduleCreateService
的实现
public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo) {
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
s.compatInfo = compatInfo;
queueOrSendMessage(H.CREATE_SERVICE, s);
}
好吧,queueOrSendMessage
这个函数我们在ActivityThread中已经看到过很多次调用很多次了,我们直接进入到真正执行创建Service实例的函数queueOrSendMessage
private void handleCreateService(CreateServiceData data) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
......
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 context = new ContextImpl();
context.init(packageInfo, null, this);
Application app = packageInfo.makeApplication(false, mInstrumentation);
context.setOuterContext(service);
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
//执行Service onCreate方法
service.onCreate();
mServices.put(data.token, service);
try {
//通知ActivityManagerService实例创建完成
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, 0, 0, 0);
} catch (RemoteException e) {
// nothing to do.
}
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to create service " + data.info.name
+ ": " + e.toString(), e);
}
}
}
函数的代码不短也不长,还是比较好理解的。首先获取Service的信息,然后调用反射创建Service实例(想想Activity实例的创建,是不是也是反射?),创建完实例后就会去执行attach方法,执行完attach方法后就会去执行onCreate方法(想想Activity,是不是也是先执行attach在执行onCreate?),执行完onCreate方法后,通知ActivityManagerService。
执行完Service实例的创建,接下来执行onStartCommand
的流程就是 startService启动流程—Service已经启动中描述的流程,我就不再分析了。