看完
Activity
的启动过程,发现Service
的启动过程相对来说就比较简单了。
要说起启动过程,就得从 startService
开始:
1.startService
根据源码的跳转,发现跳转到 ContextWrapper
这个类中,代码如下:1
2
3
4@Override
public ComponentName startService(Intent service) {
return mBase.startService(service);
}
其中 mBase
是类型是:Context
类型,如下:1
2
3
4public class ContextWrapper extends Context {
Context mBase;
......
}
而我们又知道 Context
是一个抽象类 ,实现者是 ContextImpl
,所以我们应该是查看ContextImpl
这个类中的 startService(service)
方法。
ContextImpl
中的方法定义如下:1
2
3
4
5@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
在 startService
中又调用了 startServiceCommon(service,(requirForeground:false),mUser)
这个方法,继续跟进:
2.startServiceCommon
startServiceCommon
方法如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29private 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()
点进去查看1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16/**
* @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
类:1
2
3
4public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
.....
}
果然不出所料,AMS extend IActivityManager.Stub
.
mMainThread.getApplicationThread()
首先明白mMainThread
是ActivityThread
类的实例变量,通过getApplicationThread()
方法拿到一个ApplicationThread
类的实例:1
2
3
4public ApplicationThread getApplicationThread()
{
return mAppThread;
}
而ApplicationThread
类定义如下:1
2
3private class ApplicationThread extends IApplicationThread.Stub {
.....
}
发现 ApplicationThread
是 ActivityThread
的一个内部类.并且实现了 IApplicationThread.Stub
,而我们又把这个类型传入给了AMS
,相当于远程服务拿到了一个访问应用进程的代理,类型为:IApplicationThread
总结:到目前为止,客户端拿到了远程服务的代理
(IActivityManager)
, 服务端拿到了客户端的代理(IApplicationThread)
,它们互相拿到各自进程的代理类,是它们进行进程间通信的基础。
ok ,我们回到最初那个地方:1
2
3
4ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
通过前面的分析我们知道:ActivityManager.getService().
实际就是 AMS
远程代理,最终在AMS
中完成,我们去 AMS
代码中查看下 startService
代码:
3.ActivityManagerService. startService
1 | @Override |
startServiceLocked
方法很复杂,大概如下:1
2
3
4
5
6
7
8
9
10
11ComponentName 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
如下:1
2
3
4
5
6ComponentName 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
1 | private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, |
而后又调用了 realStartServiceLocked(r, app, execInFg);
6.realStartServiceLocked
1 | private final void realStartServiceLocked(ServiceRecord r, |
其中 app.thread
是 IApplicationThread
类型,就是远程调用客户端进程里的方法,scheduleCreateService
,而我们又知道 ApplicationThread
实现了 IApplicationThread
,所以就查看 ApplicationThread
类中的 scheduleCreateService
方法,前面我们说过ApplicationThread
是 ActivityThread
的一个内部类,查看:
7.ApplicationThread.scheduleCreateService
1 | public final void scheduleCreateService(IBinder token, |
发现内部通过发送一个 CREATE_SERVICE
的消息,H
是 Handle
,继续查看:handleMessage
方法
1 | case CREATE_SERVICE: |
到 handleCreateService
中:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46private 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
的启动过程的就完成了。