Service的启动过程(基于9.0系统)
Service是Android系统中四大组件之一,在实际开发中有着非常重要的作用,这里就对Service的启动过程进行一些总结。
在Activity中可以通过startService开启一个服务,而Activity中的startService方法实际调用的是Activity父类ContextWrapper的方法,ContextWrapper的相关源码如下:
ContextWrapper类:
//Context类型,具体实现类是ContextImpl
Context mBase;
@Override
public ComponentName startService(Intent service) {
return mBase.startService(service);
}
ContextWrapper也没有直接开启服务,而是调用了mBase的startService方法,mBase的具体实现是ContextImpl《Context的创建过程》,下面看下ContextImpl类中执行开启服务的代码:
ContextImpl类:
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
//关键代码1(ActivityManager.getService()是AMS)
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), 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 new IllegalStateException(
"Not allowed to start service " + service + ": " + cn.getClassName());
}
}
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
由上面的代码可知,ContextImpl的startService又调用了startServiceCommon方法,在关键代码1处可知,调用了ActivityManager.getService()的startService方法,这里先看下ActivityManager.getService()是什么,ActivityManager的相关源码如下:
ActivityManager:
/**
* @hide
*/
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
//关键代码2
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
由ActivityManager的getService方法和关键代码2处可以知到,ActivityManager的getService方法获取的是IActivityManager类型的Binder对象,是AMS的代理,最终代码调用就到了AMS的startService方法了,这是一个进程间通信的过程,AMS开启服务的源码如下:
ActivityManagerService:
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage, int userId)
throws TransactionTooLargeException {
enforceNotIsolatedCaller("startService");
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
if (callingPackage == null) {
throw new IllegalArgumentException("callingPackage cannot be null");
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res;
try {
//关键代码3
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}
在关键代码3处,调用了ActiveServices的startServiceLocked方法,相关代码如下:
ActiveServices:
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException {
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
return cmp;
}
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
ServiceState stracker = r.getTracker();
.............
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
.............
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.longVersionCode, 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 a dead object exception was thrown -- fall through to
// restart the application.
}
}
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
//关键代码 4(app.thread是ApplicationThread)
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
}
在startServiceLocked方法中依次调用了自身的startServiceInnerLocked方法、bringUpServiceLocked方法、realStartServiceLocked方法,在关键代码 4处的app.thread指代的是ApplicationThread,它的类型是IApplicationThread,也是一个Binder,该调用是一次IPC调用,scheduleCreateService执行在客户端的Bindre线程池中,看下scheduleCreateService的源码:
ApplicationThread:
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;
//关键代码5 发送一个创建Service的handler消息
sendMessage(H.CREATE_SERVICE, s);
}
由关键代码5可知,向H类(handler)发送消息,将线程从线程池切换到了UI线程,H类处理创建服务的代码如下:
H类:
case CREATE_SERVICE://处理创建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;
H类中接收到CREATE_SERVICE消息后 ,又调用了ActivityThread的方法处理服务创建,handleCreateService源码如下:
ActivityThread:
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.
unscheduleGcIdler();
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
//关键代码6 通过反射创建service
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to instantiate service " + data.info.name
+ ": " + e.toString(), e);
}
}
try {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
//关键代码7 创建Context
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
//关键代码8 创建Application(如果存在就直接返回,不存在才去创建)
Application app = packageInfo.makeApplication(false, mInstrumentation);
//关键代码9 进行一些service初始化操作
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//关键代码10 调用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);
}
}
}
在关键代码6处通过反射创建了service实例,在关键代码7处创建了Context实例,在关键代码8处创建Application(如果存在就直接返回,不存在才去创建),在关键代码9处对service进行初始化操作,在关键代码10处调用了service的onCreate方法,到此service创建并启动完成。为了整个调用流程看起来更直观一些,下面给出了相关类的调用流程图: