本文基于Android 11,参考《Android进阶解密》一书资料。了解Service的启动和绑定流程,以及Service的Context创建过程。
由于基于分析流程,忽略很多细节分支。各位在看源码的时候,要尽可能忽略细节,分析整体流程之后,还有精力的话再去看细节。例如有些属性是在后面赋值的,如果在前面追究,难哦。
另:阅读这种流程需要很大的耐心和毅力。建议在心情愉悦想要学习的时候搭配源码一起食用。
一、Service 的启动流程
1、ContextImpl.startService
启动一个Service,通常在Activity调用startService来启动。
1
2
3
4
|
@Override
public ComponentName startService(Intent service) {
return startServiceCommon(service, false, mUser);
}
|
2、ContextImpl.startServiceCommon
startServiceCommon检查intent内容是否合法,然后做一些离开当前进程的准备操作。调用 ActivityManager.getService()获得AMS的本地引用,并调用其startService函数。
也就是说通过Binder机制跨进程通信调用了AMS的startService函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
//检查intent 的compant和package是否合法
validateServiceIntent(service);
...
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
getOpPackageName(), getAttributionTag(), user.getIdentifier());
...
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
|
通过 ActivityManager.getService()的实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
@UnsupportedAppUsage
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
@UnsupportedAppUsage
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;
}
};
|
3、AMS.startService
AMS.startService函数获取调用Pid和Uid,然后调用ActiveService的startServiceLocked函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage,
String callingFeatureId, int userId)
throws TransactionTooLargeException {
...
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res;
try {
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, callingFeatureId, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}
|
4、ActiveService.startServiceLock
ActiveService.startServiceLock函数,对一些合法性的检查,例如前台Service的权限、限制性后台Service进行延迟运行(standby)。并将要启动的信息封装成ServiceRecord。然后调用了startServiceInnerLocked函数。
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
|
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage,
@Nullable String callingFeatureId, final int userId)
throws TransactionTooLargeException {
return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
callingPackage, callingFeatureId, userId, false);
}
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage,
@Nullable String callingFeatureId, final int userId,
boolean allowBackgroundActivityStarts) throws TransactionTooLargeException {
final boolean callerFg;
if (caller != null) {
//获取调用Service的应用程序进程描述
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
if (callerApp == null) {
...
}
callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
} else {
callerFg = true;
}
//检索ServiceRecord,包括同应用和其他应用
ServiceLookupResult res =
retrieveServiceLocked(service, null, resolvedType, callingPackage,
callingPid, callingUid, userId, true, callerFg, false, false);
...
//要启动的ServiceRecord
ServiceRecord r = res.record;
...
r.lastActivity = SystemClock.uptimeMillis();
r.startRequested = true;
r.delayedStop = false;
r.fgRequired = fgRequired;
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
service, neededGrants, callingUid));
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
...
return cmp;
}
|
5、ActiveServices.startServiceInnerLocker
调用了bringUpServiceLocked函数,会将ServiceRecord添加到ServiceMap类型的smap集合,进行缓存。
1
2
3
4
5
6
7
8
|
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
r.callStart = false;
...
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
...
return r.name;
}
|
6、 ActiveService.bringUpServiceLocked
分析一:首次启动Service时,在执行bringUpServiceLocked函数,ServiceRecord是属于新创建的,而非从AMS的缓存mServices中检索而来,所以此时的ServiceRecord的ProcessRecord类型app和IApplicationThread类型thread都是null。只有启动过后的ServiceRecord才有值,才会执行sendServiceArgsLocked函数,重复调用Service的生命周期onStartCommand,而不调用onCreate函数。
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
46
47
48
|
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
//分析一:未启动过的ServiceRecord两者都是null,重复启动会执行该函数,
//会重复调用service的onStartCommand函数。
if (r.app != null && r.app.thread != null) {
sendServiceArgsLocked(r, execInFg, false);
return null;
}
...
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
final String procName = r.processName;
HostingRecord hostingRecord = new HostingRecord("service", r.instanceName);
ProcessRecord app;
if (!isolated) {
////通过AMS获取service所在进程的ProcessRecord。ProcessList=>MyProcessMap=》会缓存已创建过进程的ProcessRecord
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
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.shortInstanceName, e);
}
}
}
//如果service所在的进程未启动,通过AMS启动该进程,可以参考应用进程的启动流程
if (app == null && !permissionsReviewRequired) {
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, isolated, false)) == null) {;
bringDownServiceLocked(r);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
//等待进程启动完毕重启启动
if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}
...
return null;
}
|
7、ActiveService.realStartServiceLocked
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
//将ProcessRecord设置给ServiceRecord
r.setProcess(app);
//登记当ServiceRecord到ProcessRecordd的数组mServices,表示Service已经启动(实际未启动)
final boolean newService = app.startService(r);
boolean created = false;
try {
...
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
app.getReportedProcState());
...
} catch (DeadObjectException e) {
Slog.w(TAG, "Application dead when creating service " + r);
mAm.appDiedLocked(app, "Died when creating service");
throw e;
}
//会调用Service的onStartCommand函数
sendServiceArgsLocked(r, execInFg, true);
...
}
|
通过ProcessRecord对象的IApplicationThread引用,通过Binder机制调用了应用程序的ApplicationThread的scheduleCreateService函数。
8、ApplicationThread.scheduleCreateService
将ServiceInfo等相关信息封装到CreateServiceData中,并发送给ActivityThread的H类型的mH对象。
1
2
3
4
5
6
7
8
9
|
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);
}
|
9、H.handleMesssage
调用了ActivityThread的handleCreateService函数。
1
2
3
|
case CREATE_SERVICE:
handleCreateService((CreateServiceData)msg.obj);
break;
|
10、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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
private void handleCreateService(CreateServiceData data) {
...
//获取当前应用的描述信息LoadedApk
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
//创建Service的上下问文
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
//获取当前应用Applcation对象
Application app = packageInfo.makeApplication(false, mInstrumentation);
//通过反射创建Service对象
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);
//初始化资源
context.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
//context 与service相互绑定
context.setOuterContext(service);
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//调用Service的生命周期onCreate函数,意味Service创建完毕
service.onCreate();
//缓存Service
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);
}
}
}
|
通过ContextImpl.createAppContext创建Service的上下文context,通过packageInfo.getAppFactory().instantiateService反射获得当前Service对象service,将context与service相互绑定。然后调用service.onCreate。至此,Service创建完毕。
二、Service的绑定
1、 ContextImpl.bindService
1
2
3
4
5
6
|
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
//系统进程调用绑定服务或发送广播都会发出警告
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,
getUser());
}
|
2、ContextImpl.bindServiceCommon
在分析一,主要判断入参Executor executor或UserHandle user哪个为null,总有一个为null,但最终都是调用了LoadedApk的getServiceDispatcherCommon函数来获取ServiceDispathcer类型sd。影响只是回调代码是在主线程执行,还是线程池。这里传入ActivityThread的H对象,意味着后续连接成功回调onServiceConnected是在主线程。
分析二:通过Binder机制调用AMS的bindIsolatedService函数。
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
|
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
String instanceName, Handler handler, Executor executor, UserHandle user) {
// Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
IServiceConnection sd;
if (conn == null) {
throw new IllegalArgumentException("connection is null");
}
if (handler != null && executor != null) {
throw new IllegalArgumentException("Handler and Executor both supplied");
}
if (mPackageInfo != null) {
if (executor != null) {//分析一:无论哪个分支,都是获得ServiceConnect的本地引用sd,两者最终都是
//调用LoadedApk的getServiceDispatcherCommon
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
} else {
//正常使用走这个分支
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
}
} else {
throw new RuntimeException("Not supported in system context");
}
//检查compant and package is null ?
validateServiceIntent(service);
try {
IBinder token = getActivityToken();
if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
&& mPackageInfo.getApplicationInfo().targetSdkVersion
< android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
flags |= BIND_WAIVE_PRIORITY;
}
service.prepareToLeaveProcess(this);
//分析二:调用AMS.bindIsolatedService
int res = ActivityManager.getService().bindIsolatedService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
if (res < 0) {
throw new SecurityException(
"Not allowed to bind to service " + service);
}
return res != 0;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
|
IServiceConnection连接的创建会先从缓存中获取,避免每次都要新建。分析一:通过executor或handler创建ServiceDispatcher类型的sd,含有静态内部类InnerConnection的引用mIServiceConnection。继承自IServiceConnection.Stub,也就是InnerConnection是实现者,远程调用代理在其他进程,例如SystemServer进程中的ActiveService。
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
|
private IServiceConnection getServiceDispatcherCommon(ServiceConnection c,
Context context, Handler handler, Executor executor, int flags) {
synchronized (mServices) {
LoadedApk.ServiceDispatcher sd = null;
//从缓存获取
ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
if (map != null) {
sd = map.get(c);
}
if (sd == null) {
//分析一:通过executor或handler创建ServiceDispatcher
if (executor != null) {
sd = new ServiceDispatcher(c, context, executor, flags);
} else {
sd = new ServiceDispatcher(c, context, handler, flags);
}
if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c);
if (map == null) {
map = new ArrayMap<>();
mServices.put(context, map);
}
map.put(c, sd);
} else {
sd.validate(context, handler, executor);
}
return sd.getIServiceConnection();
}
}
|
3、AMS.bindIsolatedService
AMS经过两次重载函数bindIsolatedService调用,简单检查相关合法性。然后调用ActiveService类型的mService的bindServiceLocked函数。
4、ActiveService.bindServiceLocked
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, final IServiceConnection connection, int flags,
String instanceName, String callingPackage, final int userId)
throws TransactionTooLargeException {
//发起绑定service的app进程描述
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
...
ServiceLookupResult res =
retrieveServiceLocked(service, instanceName, resolvedType, callingPackage,
Binder.getCallingPid(), Binder.getCallingUid(), userId, true,
callerFg, isBindExternal, allowInstant);
...
ServiceRecord s = res.record;
...
//描述Service和应用程序进程之间的关联,内部维护Service、进程、IntentFilter以及所有绑定信息。
AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
//描述应用程序与service建立的一次通信(绑定)
ConnectionRecord c = new ConnectionRecord(b, activity,
connection, flags, clientLabel, clientIntent,
callerApp.uid, callerApp.processName, callingPackage);
IBinder binder = connection.asBinder();
s.addConnection(binder, c);
b.connections.add(c);
if (activity != null) {
activity.addConnection(c);
}
b.client.connections.add(c);
c.startAssociationIfNeeded();
...
//启动Service,可以参考Service的启动
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
permissionsReviewRequired) != null) {
return 0;
}
}
...
//表示Service已启动,且已返回binder,可以通过binder访问接口
if (s.app != null && b.intent.received) {
// Service is already running, so we can immediately
// publish the connection.
try {
//建立连接
c.conn.connected(s.name, b.intent.binder, false);
} catch (Exception e) {
Slog.w(TAG, "Failure sending service " + s.shortInstanceName
+ " to connection " + c.conn.asBinder()
+ " (in " + c.binding.client.processName + ")", e);
}
//第一个绑定该Service的进程,且要重绑
if (b.intent.apps.size() == 1 && b.intent.doRebind) {
requestServiceBindingLocked(s, b.intent, callerFg, true);
}
} else if (!b.intent.requested) {//首次绑定,执行此次
requestServiceBindingLocked(s, b.intent, callerFg, false);
}
...
}
|
AppBindRecord 描述应用程序进程和Service的关联,包括谁绑定了Service的ProcessRecord,绑定信息IntentBindRecord,当前服务ServiceRecord,当前应用进程的所有连接记录connections。
5、requestServiceBindingLocked
调用了ApplicationThread的scheduleBindService函数。
1
2
3
4
5
6
|
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
boolean execInFg, boolean rebind) throws TransactionTooLargeException {
...
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind, r.app.getReportedProcState());
...
}
|
6、ApplicationThread.scheduleBindService
将数据封装 BindServiceData,发送个ActivityThread的H类型的mH处理。
1
2
3
4
5
6
7
8
9
|
public final void scheduleBindService(IBinder token, Intent intent,
boolean rebind, int processState) {
updateProcessState(processState, false);
BindServiceData s = new BindServiceData();
s.token = token;
s.intent = intent;
s.rebind = rebind;
sendMessage(H.BIND_SERVICE, s);
}
|
7 、 H.handleMessage
1
2
|
case BIND_SERVICE:
handleBindService((BindServiceData)msg.obj);
|
8、ActivityThread.handleBindService
handleBindService函数有两个分支,即是否重新绑定。
如果当前进程第一个与Service绑定,且调用过了onUbBinder方法,那么这里的data.rebind将为true,直接执行Service的onRebind函数即可。另外一种就是没有绑定过,那么需要执行Service的onBind函数。然后还要执行AMS的publishService函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);
if (s != null) {
...
try {
if (!data.rebind) {
IBinder binder = s.onBind(data.intent);
ActivityManager.getService().publishService(
data.token, data.intent, binder);
} else {
s.onRebind(data.intent);
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
}
}
|
9、AMS.publishService
1
2
3
4
5
6
7
8
9
10
11
12
|
public void publishService(IBinder token, Intent intent, IBinder service) {
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
synchronized(this) {
if (!(token instanceof ServiceRecord)) {
throw new IllegalArgumentException("Invalid service token");
}
mServices.publishServiceLocked((ServiceRecord)token, intent, service);
}
}
|
10、ActiveService.publishServiceLocked
分析一:可见在第4步bindServiceLocked函数,IntentBindRecord对象的属性binder、requested、received都是false。
在ServiceRecord的所有连接记录connections中,通过intent查找对应之前已经保存的ConnectionRecord,并调用其IServiceConnection的connected函数。
在第2步的时候调用bindServiceCommon函数时,会创建ServiceDispatcher时,内部持有InnerConnection实例,这里的IServiceConnection代理引用指向该InnerConnection实例,这里会调用其connected函数。
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
|
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
final long origId = Binder.clearCallingIdentity();
try {
if (r != null) {
Intent.FilterComparison filter
= new Intent.FilterComparison(intent);
IntentBindRecord b = r.bindings.get(filter);
if (b != null && !b.received) {//分析1
b.binder = service;
b.requested = true;
b.received = true;
ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
for (int conni = connections.size() - 1; conni >= 0; conni--) {
ArrayList<ConnectionRecord> clist = connections.valueAt(conni);
for (int i=0; i<clist.size(); i++) {
ConnectionRecord c = clist.get(i);
if (!filter.equals(c.binding.intent.intent)) {
...
continue;
}
...
try {
c.conn.connected(r.name, service, false);
} catch (Exception e) {
Slog.w(TAG, "Failure sending service " + r.shortInstanceName
+ " to connection " + c.conn.asBinder()
+ " (in " + c.binding.client.processName + ")", e);
}
}
}
}
serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
|
11、InnerConnection.connected
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
private static class InnerConnection extends IServiceConnection.Stub {
@UnsupportedAppUsage
final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
InnerConnection(LoadedApk.ServiceDispatcher sd) {
mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
}
public void connected(ComponentName name, IBinder service, boolean dead)
throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
sd.connected(name, service, dead);
}
}
}
|
12、ServiceDispatcher.connected
这里调用了 mActivityThread.post(new RunConnection(name, service, 0, dead)),执行RunConnection的run函数。这里的话run函数执行代码又回到了应用进程的主线程。
1
2
3
4
5
6
7
8
9
|
public void connected(ComponentName name, IBinder service, boolean dead) {
if (mActivityExecutor != null) {
mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
} else if (mActivityThread != null) {
mActivityThread.post(new RunConnection(name, service, 0, dead));
} else {
doConnected(name, service, dead);
}
}
|
13、RunConnection.run
RunConnection是ServiceDispatcher的内部类,这里执行SD的doConnected函数。
1
2
3
4
5
6
7
|
public void run() {
if (mCommand == 0) {
doConnected(mName, mService, mDead);
} else if (mCommand == 1) {
doDeath(mName, mService);
}
}
|
14、ServiceDispatcher.doConnected
这里调用了ServiceConnection对象的onServiceConnected函数,也就是我们发起绑定,调用context.bindService的参数。
1
2
3
4
5
|
public void doConnected(ComponentName name, IBinder service, boolean dead) {
...
mConnection.onServiceConnected(name, service);
...
}
|
到此,Service的绑定流程分析完毕。
三、Service的Context
在第一节Service的启动流程最后函数调用了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
26
27
28
29
30
31
32
33
34
35
36
|
private void handleCreateService(CreateServiceData data) {
unscheduleGcIdler();
//应用的描述信息
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
//分析一
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
Application app = packageInfo.makeApplication(false, mInstrumentation);
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);
context.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
//分析二
context.setOuterContext(service);
//分析三
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
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);
}
}
}
|
分析一:通过ContextImpl的静态函数createAppContext返回了一个ContextImpl类型的context。createAppContext又调用了重载函数createAppContext。直接新建了ContextImpl实例context,构造函数传递了ActivityThread类型的mainThread和LoadedApk类型的packageInfo。并给context设置了资源环境和是否Syetem属性。
1
2
3
4
5
6
7
8
9
10
11
12
|
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
return createAppContext(mainThread, packageInfo, null);
}
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo,
String opPackageName) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, null,
0, null, opPackageName);
context.setResources(packageInfo.getResources());
context.mIsSystemOrSystemUiContext = isSystemOrSystemUI(context);
return context;
}
|
ContextImpl类有一个Context类型的mOuterContext属性,在构造函数时指向了自己。
回到handleCreateService函数的分析二,在创建好Service对象service之后,将service作为参数传递给了context.setOuterContext函数。Service本身继承自ContextWrapper,ContextWrapper又是Context的子类。这时候的setOuterContext函数将service设置给了context的mOuterContext属性。意味着当前上下文context持有当前新建的service引用。
在分析三,调用了service.attach函数,context并作为第一个参数被传入。attach函数又调用了attachBaseContext函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public final void attach(
Context context,
ActivityThread thread, String className, IBinder token,
Application application, Object activityManager) {
attachBaseContext(context);
mThread = thread;
mClassName = className;
mToken = token;
mApplication = application;
mActivityManager = (IActivityManager)activityManager;
mStartCompatibility = getApplicationInfo().targetSdkVersion
< Build.VERSION_CODES.ECLAIR;
setContentCaptureOptions(application.getContentCaptureOptions());
}
|
attachBaseContext调用了父类ContextWrapper的attachBaseContext函数
1
2
3
4
5
6
7
|
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
if (newBase != null) {
newBase.setContentCaptureOptions(getContentCaptureOptions());
}
}
|
ContextWrapper将一路传递过来的上下文base设置给你了mBase属性。
1
2
3
4
5
6
|
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
|
也就是说,我们在启动Service时,会同时创建Service的上下文context,并将其存储到Service的父类ContextWrapper的mBases属性中,同时context也会有当前Service引用,存储在mOuterContext变量中。
总结
- Service的启动和绑定从AMS转移到ActiveService
- Service的启动,会先判断进程是否创建,提前启动进程,再启动自己。
- Service重复启动,会重复调用onStratCommand及后续生命周期函数。
- Service的绑定,会先走一趟Service的启动流程,再绑定。
- 应用进程与SytemServer进程(AMS、ActiveService)的交互式通过Binder机制进行,通过AIDL各持有双方接口。应用进程通过H对象,将现成重新切回主线程(所有应用夸进程通信应如此)。
- Service在应用和AMS两边都会做缓存,以便快速在找到使用。应用程序存储在ArrayMap<IBinder, Service>类型的mServices;ActiveService则是ArraySet<ServiceRecord>类型的mServices。
|