bindService 调用流程
API 28
一、bindService() 调用流程时序图
二、bindService() 调用流程文字描述
bindService() ->
ContextImpl#bindService() ->
ContextImpl#bindServiceCommon() ->
// mPackageInfo 类型为 LoadedApk
// getServiceDispatcher() 方法调用了 LoadedApk#ServiceDispatcher#getServiceDispatcher(),最终返回 LoadedApk#ServiceDispatcher#InnerConnection
IServiceConnection sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
AMS#bindService() ->
ActiveServices#bindServiceLocked() ->
retrieveServiceLocked() ->
// 有个 ServiceMap 内部类,用于绑定用户和其对应的 Service
ServiceMap smap = getServiceMapLocked(userId);
// comp 默认不为空
final ComponentName comp = service.getComponent();
从 smap 中获取 ServiceRecord 对象:
a 若存在,则取出
b 若不存在,则创建 ServiceRecord 对象
作为参数构造 ServiceLookupResult 对象实例后返回
bringUpServiceLocked() ->
若 Service 已经启动
if (r.app != null && r.app.thread != null) {
sendServiceArgsLocked(r, execInFg, false);
return null;
}
若 Service 没有启动
获取 Service 所在进程是否存在
存在:realStartServiceLocked()
ActivityThread#ApplicationThread#scheduleCreateService()
// 从 AMS 所在进程转到客户端进程
ActivityThread#handleCreateService()
// 获取 LoadedApk 实例
LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);
// instantiateService() 方法反射创建 Service 实例
service = packageInfo.getAppFactory().instantiateService(cl, data.info.name, data.intent);
// 创建 ContextImpl 实例
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
// 将创建的 Service 设置为 ContextImpl 的 mOuterContext
context.setOuterContext(service);
// 创建 Application(有就不创建,没有就创建)
packageInfo.makeApplication(false, mInstrumentation);
// 调用 Service#onCreate(),CREATE_SERVICE 消息处理完毕
service.onCreate();
// 这里是 AMS 所在进程
requestServiceBindingsLocked()
requestServiceBindingLocked()
ActivityThread#ApplicationThread#scheduleBindService()
// 从 AMS 所在进程转到客户端进程
ActivityThread#handleBindService()
// 调用 Service#onBind()
s.onBind(data.intent);
ActivityManager.getService().publishService()
ActivityManagerService#publishService()
ActiveServices#publishServiceLocked()
IntentBindRecord b = r.bindings.get(filter);
b.binder = service;
b.requested = true;
b.received = true;
// conn:ConnectionRecord 类的成员变量 IServiceConnection
// ConnectionRecord 在 ActiveServices#bindServiceLocked() 中创建,其第三个参数即 conn
// 一直往上找,该参数是在一开始的 ContextImpl#bindServiceCommon() 中被赋值,实际类型为 LoadedApk#ServiceDispatcher#InnerConnection
// IServiceConnection,实现了 Binder 机制?
// 在 LoaeddApk 中发现 static class InnerConnection extends IServiceConnection.Stub,证明 IServiceConnection 确实实现了 Binder 机制
// 因为 conn 实际类型为 LoadedApk#ServiceDispatcher#InnerConnection
// 所以 conn.connected 对应 LoadedApk#ServiceDispatcher#InnerConnection#connected()
c.conn.connected(r.name, service, false);
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
sd.connected(name, service, dead);
// mActivityThread 是在 ContextImpl#bindService() 中被赋值,类型为 Handler,不为空
if (mActivityThread != null) {
// RunConnection implements Runnable,查看其 run() 方法
mActivityThread.post(new RunConnection(name, service, 0, dead));
RunConnection#run():
doConnected(mName, mService, mDead);
// 这里的 service 是从 ActivityThread#handleBindService() 方法中传下来的
// IBinder binder = s.onBind(data.intent);
// ActivityManager.getService().publishService(data.token, data.intent, binder);
// publishService() 方法的第三个参数 binder 是 onServiceConnected() 方法的第二个参数 service
// 而 binder 是 Service#onBind() 的返回值,这也是我们平时在写 Service#onBind() 方法时,方法要返回一个远程 Binder 接口的实现类
// 且 mConnection 是我们在代码中创建的 ServiceConnection 实例,通过 ContextImpl#bindService() 传下来
// 因此我们在 Connection#onServiceConnected() 方法中就能获取到远程 Binder 本地代理的原因
mConnection.onServiceConnected(name, service);
} else {
doConnected(name, service, dead);
}
return null;
不存在:略(下次说)
// s.app:Service 对应的 ProcessRecord 不为空
// b.intent.received:在 bindService 过程中调用 publishService() 时,当前值被置为 true
if (s.app != null && b.intent.received)
// Service 已经启动,现在开始连接
c.conn.connected(s.name, b.intent.binder, false);
// b.intent.requested:在 bindService 过程中调用 publishService() 时,当前值被置为 true
else if (!b.intent.requested) // if 判断为 false
requestServiceBindingLocked() // 不执行