看完
Activity
的启动过程,发现Service
的启动过程相对来说就比较简单了。
要说起启动过程,就得从 startService
开始:
1.startService
根据源码的跳转,发现跳转到 ContextWrapper
这个类中,代码如下:
@Override
public ComponentName startService(Intent service) {
return mBase.startService(service);
}
复制代码
其中 mBase
是类型是:Context
类型,如下:
public class ContextWrapper extends Context {
Context mBase;
......
}
复制代码
而我们又知道 Context
是一个抽象类 ,实现者是 ContextImpl
,所以我们应该是查看ContextImpl
这个类中的 startService(service)
方法。
ContextImpl
中的方法定义如下:
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
复制代码
在 startService
中又调用了 startServiceCommon(service,(requirForeground:false),mUser)
这个方法,继续跟进:
2.startServiceCommon
startServiceCommon
方法如下:
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
//校验要启动的service
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
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();
}
}
复制代码
这里面有几个需要说明一下:
ActivityManager.getService()
点进去查看
/**
* @hide
*/
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
复制代码
首先是返回的类型是 IActivityManager
类型,其中在create
方法中,拿到远程服务的Binder
对象,其中IActivityManager.Stub.asInterface(b)
不知道大家有没有想起AIDL
这就很熟悉了,就是拿到远程服务的代理对象:IActivityManager
,通过代理对象调用远程的方法,是应用进程与服务进程通信的媒介,如果没猜错的话就是在ActivityManagerService
中实现了,查看ActivityManagerService
类:
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
.....
}
复制代码
果然不出所料,AMS extend IActivityManager.Stub
.
mMainThread.getApplicationThread()
首先明白mMainThread
是ActivityThread
类的实例变量,通过getApplicationThread()
方法拿到一个ApplicationThread
类的实例:
public ApplicationThread getApplicationThread()
{
return mAppThread;
}
复制代码
而ApplicationThread
类定义如下:
private class ApplicationThread extends IApplicationThread.Stub {
.....
}
复制代码
发现 ApplicationThread
是 ActivityThread
的一个内部类.并且实现了 IApplicationThread.Stub
,而我们又把这个类型传入给了AMS
,相当于远程服务拿到了一个访问应用进程的代理,类型为:IApplicationThread
总结:到目前为止,客户端拿到了远程服务的代理
(IActivityManager)
, 服务端拿到了客户端的代理(IApplicationThread)
,它们互相拿到各自进程的代理类,是它们进行进程间通信的基础。
ok ,我们回到最初那个地方:
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
复制代码
通过前面的分析我们知道:ActivityManager.getService().
实际就是 AMS
远程代理,最终在AMS
中完成,我们去 AMS
代码中查看下 startService
代码:
3.ActivityManagerService. startService
@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 {
// 又调用了startServiceLocked 方法
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}
复制代码
startServiceLocked
方法很复杂,大概如下:
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException {
.....
ServiceRecord r = res.record;//启动service的信息保存在 serviceRecord 中
....
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
return cmp;
.....
}
复制代码
内部又调用了:startServiceInnerLocked
方法
4.startServiceInnerLocked
如下:
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
...
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
...
}
复制代码
又调用: bringUpServiceLocked
5.bringUpServiceLocked
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
....
realStartServiceLocked(r, app, execInFg);
}
复制代码
而后又调用了 realStartServiceLocked(r, app, execInFg);
6.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);
....
}
复制代码
其中 app.thread
是 IApplicationThread
类型,就是远程调用客户端进程里的方法,scheduleCreateService
,而我们又知道 ApplicationThread
实现了 IApplicationThread
,所以就查看 ApplicationThread
类中的 scheduleCreateService
方法,前面我们说过ApplicationThread
是 ActivityThread
的一个内部类,查看:
7.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);
}
复制代码
发现内部通过发送一个 CREATE_SERVICE
的消息,H
是 Handle
,继续查看: handleMessage
方法
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) {
// 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 {
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 {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
//创建context
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
//创建Application
Application app = packageInfo.makeApplication(false, mInstrumentation);
//通过attach 方法,将context application ,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.onCreate();
ok ,调用了 onCreate
方法,至此,service
的启动过程的就完成了。