源码分析:Service的启动过程(startService)

ContextWrapper#startService

Service的启动过程从ContextWrapper的startService开始。这是因为ContextWrapper是Activity,Service和Application的父类。所以Activity,Service调用startService时最终是调用其父类ContextWrapper的startService方法。

1
2
3
4
@Override
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
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, mUser);
}

又调用了startServiceCommon方法

ContextImpl#startServiceCommon(API25)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private ComponentName startServiceCommon(Intent service, UserHandle user) {
try {
//...

ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), getOpPackageName(), user.getIdentifier());

//...

return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}

ActivityManagerNative.getDefault()方法得到一个AMS对象。

ContextImpl#startServiceCommon(API26)

在API26中,该方法的实现有所不同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private 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
@Override
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
2
3
4
5
6
7
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, String callingPackage, final int userId)
throws TransactionTooLargeException {
//...

return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}

继续调用startServiceInnerLocked方法

ActiveServices#startServiceInnerLocked

1
2
3
4
5
6
7
8
9
10
11
12
13
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
//...

String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
if (error != null) {
return new ComponentName("!!", error);
}

//...

return r.name;
}

其中r是一个ServiceRecord类型的参数,ServiceRecord一直贯穿着整个Service的启动过程。startServiceInnerLocked方法并没有完成具体的启动操作,而是把后续的工作交给了bringUpServiceLocked方法。

ActiveServices#bringUpServiceLocked

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
//...

final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;

if (!isolated) {
if (app != null && app.thread != null) { //如果服务所在进程已经启动
try {
realStartServiceLocked(r, app, execInFg);
return null;
}
}
}
//...

return null;
}

继续调用realStartServiceLocked方法,从名字上看,这个方法应该是真正地启动一个Service。

ActiveServices#realStartServiceLocked

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
//...

try {
//...

app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState); //创建Service对象并调用其onCreate方法

}

//...

sendServiceArgsLocked(r, execInFg, true); //调用Service的其他方法,如onStartCommand

//...
}

app.thread对象是IApplicationThread类型,最终实现类是ActivityThread的内部类ApplicationThread,因此只需看ApplicationThread的scheduleCreateService方法即可

ActivityThread.ApplicationThread#scheduleCreateService

1
2
3
4
5
6
7
8
9
10
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);
}

这个过程和Activity的启动过程类似,都是通过发送消息给H来完成。

1
2
3
4
5
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;

H对这个消息的处理是调用ActivityThread的handleCreateService方法

ActivityThread#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
private void handleCreateService(CreateServiceData data) {
//...

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();
}

try {

ContextImpl context = ContextImpl.createAppContext(this, packageInfo); //创建ContextImpl对象
context.setOuterContext(service);

Application app = packageInfo.makeApplication(false, mInstrumentation); //创建Application对象(如果还没创建过的话)
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault()); //通过Service的attach方法和ContextImpl建立联系
service.onCreate(); //调用Service的onCreate方法
mServices.put(data.token, service); //mServices是一个ArrayMap<IBinder, Service>对象,这里将该Service对象存储到一个列表中

//...
}
}

可以看出,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
15
private 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
2
3
4
5
6
7
8
9
10
11
public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
int flags ,Intent args) {
ServiceArgsData s = new ServiceArgsData();
s.token = token;
s.taskRemoved = taskRemoved;
s.startId = startId;
s.flags = flags;
s.args = args;

sendMessage(H.SERVICE_ARGS, s);
}

也是发送一条消息给H,H是这样处理的

1
2
3
4
case 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void handleServiceArgs(ServiceArgsData data) {
Service s = mServices.get(data.token); //获取相应的服务
if (s != null) {
try {

if (!data.taskRemoved) {
res = s.onStartCommand(data.args, data.flags, data.startId); //调用onStartCommand方法
}

//...
} catch (Exception e) {
//...
}
}
}

最终在该方法调用了Service的onStartCommand方法。Service的启动过程到此分析完毕。

参考

  • 《Android开发艺术探索》
-------------    本文到此结束  感谢您的阅读    -------------
0%