文字描述
1,注册时,在ContentService中,uri的"/"将uri分成各个segment,每个segment创建一个ObserverNode。
在与uri完全匹配的那个Node中,将ContentObserver保存进去。
2,notifyChange时,uri会找到匹配的ObserverNode,然后取出这个Node中所有的ContentObserver,然后告诉这个ContentObserver。
注册监听
ContentResolver {
registerContentObserver(@NonNull Uri uri, boolean notifyForDescendants,
@NonNull ContentObserver observer) {
registerContentObserver(
ContentProvider.getUriWithoutUserId(uri),
notifyForDescendants,
observer,
ContentProvider.getUserIdFromUri(uri, mContext.getUserId()));
}
registerContentObserver(Uri uri, boolean notifyForDescendents,
ContentObserver observer, @UserIdInt int userHandle) {
// binder到ContentService
getContentService().registerContentObserver(
uri,
notifyForDescendents, //发送子uri时,此observer是否接收。父uri发生变化,子uri的observer会接收到回调
observer.getContentObserver(), // ContentObserver里的IContentObserver
userHandle,
mTargetSdkVersion);
}
}
到system server
ContentService {
registerContentObserver(Uri uri,., IContentObserver observer, .) {
mRootNode.addObserverLocked(uri, observer, ...);
}
class ObserverNode {
addObserverLocked(Uri uri, IContentObserver observer, ..) {
addObserverLocked(uri, 0, observer, ...);
}
addObserverLocked(Uri uri, int index, IContentObserver observer, ...) {
String segment = getUriSegment(uri, index); //此处index=0,获取的是authority。
...
ObserverNode node = new ObserverNode(segment); //authority作为每个ObserverNode的key
mChildren.add(node);
node.addObserverLocked(uri, index+1, observer, ...); // 循环调用到本方法,但是node不是mRootNode了,而是mRootNode.mChildren中的node。
}
// 为了方便看,下面这个函数,和上面函数是同一个,只是走的逻辑分支不同。
addObserverLocked(Uri uri, int index, IContentObserver observer, ...) {
if (index == countUriSegments(uri)) { //uri的authority+path一共几个段
mObservers.add(new ObserverEntry(observer, ...));
return;
}
...
}
}
}
注册的模型
mRootNode(包含ObserverEntry)
ObserverNode(包含ObserverEntry) ObserverNode(包含ObserverEntry)
ObserverNode(包含ObserverEntry) ObserverNode(包含ObserverEntry)
通知变化
ContentResolver {
notifyChange(Uri uri, ContentObserver contentObserver) {
..
}
//最终调到
notifyChange(@NonNull Uri uri, ContentObserver observer, boolean syncToNetwork,
@UserIdInt int userHandle) {
// 调到ContentService中
getContentService().notifyChange(
uri,
observer == null ? null : observer.getContentObserver(),
observer != null && observer.deliverSelfNotifications(),
syncToNetwork ? NOTIFY_SYNC_TO_NETWORK : 0,
userHandle,
mTargetSdkVersion,
mContext.getPackageName());
}
}
进入到system server的ContentService
ContentService {
notifyChange(Uri uri, ...) {
// 获取calls
ArrayList<ObserverCall> calls = new ArrayList<>();
mRootNode.collectObserversLocked(uri, 0, observer, observerWantsSelfNotifications,
flags, userHandle, calls);
for(用oc遍历所有calls) {
// oc.mObserver 是IContentObserver
// oc.mSelfChange 的意思:接收change的contentObserver,就是发送notify的observier。为true有2个条件:1,是contentResolver.notify(..)中有要传入ContentObserver参数作为发送的observer;2是ContentObserver的deliverSelfNotifications()返回true。
oc.mObserver.onChange(oc.mSelfChange, uri, userHandle);
}
}
class ObserverNode {
collectObserversLocked(Uri uri, int index, ..., ArrayList<ObserverCall> calls) {
int segmentCount = countUriSegment(uri);
if (index < segmentCount) {
collectMyObserversLocked(...); //第一次是收集mRootNode里的mObservers中的ObserverEntry,里面存储了注册的ContentObserver。
}
for () {
//找到与 当前segment 匹配的ObserverNode
// observerNode再执行本函数,找到这个Node的所有ObserverEntry。
}
}
}
}
关于调用顺序
比如在MyActivity中,注册了3个uri的监听。当此uri变化时,3个监听回调的顺序是不确定的。
我写了个demo测试过。并且A\B\C的调用顺序每次都是随机的。
原因:我猜是binder线程的原因