public abstract class ContentResolver { ...... public final void registerContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer) { try { getContentService().registerContentObserver(uri, notifyForDescendents, observer.getContentObserver()); } catch (RemoteException e) { } } ...... }
public abstract class ContentResolver { ...... public static IContentService getContentService() { if (sContentService != null) { return sContentService; } IBinder b = ServiceManager.getService(CONTENT_SERVICE_NAME); ...... sContentService = IContentService.Stub.asInterface(b); ...... return sContentService; } private static IContentService sContentService; ...... }
public abstract class ContentObserver { ...... private Transport mTransport; ...... private static final class Transport extends IContentObserver.Stub { ContentObserver mContentObserver; public Transport(ContentObserver contentObserver) { mContentObserver = contentObserver; } ...... } ...... public IContentObserver getContentObserver() { synchronized(lock) { if (mTransport == null) { mTransport = new Transport(this); } return mTransport; } } ...... }
public final class ContentService extends IContentService.Stub { ...... private final ObserverNode mRootNode = new ObserverNode(""); ...... public void registerContentObserver(Uri uri, boolean notifyForDescendents, IContentObserver observer) { ...... synchronized (mRootNode) { mRootNode.addObserverLocked(uri, observer, notifyForDescendents, mRootNode); ...... } } ...... }
public final class ContentService extends IContentService.Stub { ...... public static final class ObserverNode { ...... private String mName; private ArrayList<ObserverNode> mChildren = new ArrayList<ObserverNode>(); private ArrayList<ObserverEntry> mObservers = new ArrayList<ObserverEntry>(); public ObserverNode(String name) { mName = name; } private String getUriSegment(Uri uri, int index) { if (uri != null) { if (index == 0) { return uri.getAuthority(); } else { return uri.getPathSegments().get(index - 1); } } else { return null; } } private int countUriSegments(Uri uri) { if (uri == null) { return 0; } return uri.getPathSegments().size() + 1; } public void addObserverLocked(Uri uri, IContentObserver observer, boolean notifyForDescendents, Object observersLock) { addObserverLocked(uri, 0, observer, notifyForDescendents, observersLock); } private void addObserverLocked(Uri uri, int index, IContentObserver observer, boolean notifyForDescendents, Object observersLock) { // If this is the leaf node add the observer if (index == countUriSegments(uri)) { mObservers.add(new ObserverEntry(observer, notifyForDescendents, observersLock)); return; } // Look to see if the proper child already exists String segment = getUriSegment(uri, index); if (segment == null) { throw new IllegalArgumentException("Invalid Uri (" + uri + ") used for observer"); } int N = mChildren.size(); for (int i = 0; i < N; i++) { ObserverNode node = mChildren.get(i); if (node.mName.equals(segment)) { node.addObserverLocked(uri, index + 1, observer, notifyForDescendents, observersLock); return; } } // No child found, create one ObserverNode node = new ObserverNode(segment); mChildren.add(node); node.addObserverLocked(uri, index + 1, observer, notifyForDescendents, observersLock); } ...... } ...... }