ContextWrapper#startService
Service的启动过程从ContextWrapper的startService开始。这是因为ContextWrapper是Activity,Service和Application的父类。所以Activity,Service调用startService时最终是调用其父类ContextWrapper的startService方法。1
2
3
4
public ComponentName startService(Intent service) {
return mBase.startService(service);
}
其中mBase的定义如下1
Context mBase;
mBase的实际类型是ContextImpl。ContextWrapper实现方法的时候调用了mBase的方法,即调用了ContextImpl类的方法。ContextWrapper和ContextImpl的这种关系是一种典型的被称为装饰模式的设计模式。Activity被创建时会通过attach方法与一个ContextImpl对象关联起来,这个ContextImpl对象就是mBase。
ContextImpl#startService
接着来看ContextImpl的startService方法实现1
2
3
4
5
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, mUser);
}
又调用了startServiceCommon方法
ContextImpl#startServiceCommon(API25)
1 | private ComponentName startServiceCommon(Intent service, UserHandle user) { |
ActivityManagerNative.getDefault()方法得到一个AMS对象。
ContextImpl#startServiceCommon(API26)
在API26中,该方法的实现有所不同1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
//...
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
//...
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
虽然实现有所不同,但ActivityManager.getService()方法返回的也是一个AMS对象。
ActivityManagerService#startService
接着看AMS的startService实现1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, String callingPackage, int userId)
throws TransactionTooLargeException {
//...
synchronized(this) {
//...
ComponentName res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid, callingPackage, userId);
return res;
}
}
可以看到又调用了mServices对象的startServiceLocked方法。mServices对象的类型是ActiveServices,ActiveServices是一个辅助AMS进行Service管理的类,包括Service的启动、绑定和停止等。
ActiveServices#startServiceLocked
1 | ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, |
继续调用startServiceInnerLocked方法
ActiveServices#startServiceInnerLocked
1 | ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r, |
其中r是一个ServiceRecord类型的参数,ServiceRecord一直贯穿着整个Service的启动过程。startServiceInnerLocked方法并没有完成具体的启动操作,而是把后续的工作交给了bringUpServiceLocked方法。
ActiveServices#bringUpServiceLocked
1 | private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, |
继续调用realStartServiceLocked方法,从名字上看,这个方法应该是真正地启动一个Service。
ActiveServices#realStartServiceLocked
1 | private final void realStartServiceLocked(ServiceRecord r, |
app.thread对象是IApplicationThread类型,最终实现类是ActivityThread的内部类ApplicationThread,因此只需看ApplicationThread的scheduleCreateService方法即可
ActivityThread.ApplicationThread#scheduleCreateService
1 | public final void scheduleCreateService(IBinder token, |
这个过程和Activity的启动过程类似,都是通过发送消息给H来完成。1
2
3
4
5case 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;
H对这个消息的处理是调用ActivityThread的handleCreateService方法
ActivityThread#handleCreateService
1 | private void handleCreateService(CreateServiceData data) { |
可以看出,Service的创建和Activity的创建差不多,都是要先看看是否创建了Application对象(没有就要创建,已经有了就直接返回之前创建的Application对象),创建ContextImpl对象并通过attach方法与之建立联系,最后调用onCreate方法。
ActiveServices#sendServiceArgsLocked
那么Service的onStartCommand方法是怎么调用的呢,前面说过,该方法的调用是从ActiveServices的sendServiceArgsLocked方法开始的1
2
3
4
5
6
7
8
9
10
11
12
13
14
15private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
boolean oomAdjusted) throws TransactionTooLargeException {
//...
while (r.pendingStarts.size() > 0) {
//...
try {
//...
r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
}
//...
}
}
可以看出,又回到了ActivityThread,调用ActivityThread的内部类ApplicationThread的scheduleServiceArgs方法。
ActivityThread.ApplicationThread#scheduleServiceArgs
1 | public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId, |
也是发送一条消息给H,H是这样处理的1
2
3
4case SERVICE_ARGS:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
handleServiceArgs((ServiceArgsData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
调用了ActivityThread的handleServiceArgs方法
ActivityThread#handleServiceArgs
1 | private void handleServiceArgs(ServiceArgsData data) { |
最终在该方法调用了Service的onStartCommand方法。Service的启动过程到此分析完毕。
参考
- 《Android开发艺术探索》