1.1 Service相关数据结构
Service相关数据结构1.2 Service Bind & Unbind流程
BindService相关流程图2.1 bindServiceLocked 解析
bindServiceLocked
- 通过
retrieveServiceLocked()
, 根据用户传递进来Intent
来检索相对应的服务 - 通过
retrieveAppBindingLocked()
。创建AppBindRecord
对象记录着当前ServiceRecord
,intent
以及发起方的进程信息。 - 通过
bringUpServiceLocked()
拉起目标服务;
2.2 retrieveServiceLocked
查找相应的servicerecord
,如果没有则创建;
2.3 retrieveAppBindingLocked
创建AppBindRecord
对象;
数据流程
servicerecord -> appbindrecord -> connectionrecord --save->ActiveServices
2.4 bringUpServiceLocked
作用:拉起service
和 startService
一致;
-
bringUpServiceLocked
中根据app ?= null
, 调用startProcessLocked
启动新进程; -
realStartServiceLocked
中根据传递的命令调用CreateService BindService UnBindeService
-
RunConnection
分发命令,调用客户端onServiceConnect & onServiceDisConnect
2.5 绑定service解析
handleBindService
最终调用service onBind
,获得服务端返回的binder
;通过pulishService
发布到AMS
;
-
AMS
中service
相关的执行方法被委托给ActiveServices
;ActiveServices
根据ServiceRecord
找到ConnectionRecord
,然后调用对应IServiceConnection
的connected
方法; -
IServiceConnection.Stub.Proxy
会调用servicedispatcher
的connected
方法, - 在
sd
的connected
中,会往主线程post RunConnection
对象,RunConnection
是线程对象,run
方法中会调用sd
的doConnected
方法, - 由于
sd
在创建保存了ServiceConnection
对象,所以也就调用了Client
的的conn
对象,并传递了service
端返回的binder
; -
ConnectionRecord
创建于ActivieServices
中,被添加到mServiceConnections
中,mServiceConnections
根据connection.asBinder
,记录了不同servicerecord
的连接;
2.6 PublishServie
调用service onBind
之后,通过publish
向AMS发布该service
,目的是让Client
通过AMS
获取该service Binder
2.7 ActiveServices::publishServiceLocked
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) {
b.binder = service;
b.requested = true;
b.received = true;
for (int conni=r.connections.size()-1; conni>=0; conni--) {
ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
for (int i=0; i<clist.size(); i++) {
ConnectionRecord c = clist.get(i);
if (!filter.equals(c.binding.intent.intent)) {
continue;
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Publishing to: " + c);
try {
c.conn.connected(r.name, service); // 调用ServiceConnection connected
} catch (Exception e) {
}
}
}
}
serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false); // remove ANR message
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
AMS
遍历找到ConnectionRecord
网友评论