contentObserver

文字描述

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线程的原因

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值