Android应用程序组件Content Provider的共享数据更新通知机制分析(3)
-
public class ArticlesAdapter {
-
......
-
-
public long insertArticle(Article article) {
-
ContentValues values = new ContentValues();
-
values.put(Articles.TITLE, article.getTitle());
-
values.put(Articles.ABSTRACT, article.getAbstract());
-
values.put(Articles.URL, article.getUrl());
-
-
Uri uri = resolver.insert(Articles.CONTENT_URI, values);
-
String itemId = uri.getPathSegments().get(1);
-
-
return Integer.valueOf(itemId).longValue();
-
}
-
-
......
-
}
-
public class ArticlesProvider extends ContentProvider {
-
......
-
-
@Override
-
public Uri insert(Uri uri, ContentValues values) {
-
if(uriMatcher.match(uri) != Articles.ITEM) {
-
throw new IllegalArgumentException("Error Uri: " + uri);
-
}
-
-
SQLiteDatabase db = dbHelper.getWritableDatabase();
-
-
long id = db.insert(DB_TABLE, Articles.ID, values);
-
if(id < 0) {
-
throw new SQLiteException("Unable to insert " + values + " for " + uri);
-
}
-
-
Uri newUri = ContentUris.withAppendedId(uri, id);
-
resolver.notifyChange(newUri, null);
-
-
return newUri;
-
}
-
-
......
-
}
-
resolver.notifyChange(newUri, null);
这个函数定义在frameworks/base/core/java/android/content/ContentResolver.java文件中:
-
public abstract class ContentResolver {
-
......
-
-
public void notifyChange(Uri uri, ContentObserver observer) {
-
notifyChange(uri, observer, true /* sync to network */);
-
}
-
-
public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
-
try {
-
getContentService().notifyChange(
-
uri, observer == null ? null : observer.getContentObserver(),
-
observer != null && observer.deliverSelfNotifications(), syncToNetwork);
-
} catch (RemoteException e) {
-
}
-
}
-
-
......
-
}
-
public final class ContentService extends IContentService.Stub {
-
......
-
-
public void notifyChange(Uri uri, IContentObserver observer,
-
boolean observerWantsSelfNotifications, boolean syncToNetwork) {
-
......
-
-
try {
-
ArrayList<ObserverCall> calls = new ArrayList<ObserverCall>();
-
synchronized (mRootNode) {
-
mRootNode.collectObserversLocked(uri, 0, observer, observerWantsSelfNotifications,
-
calls);
-
}
-
final int numCalls = calls.size();
-
for (int i=0; i<numCalls; i++) {
-
ObserverCall oc = calls.get(i);
-
try {
-
oc.mObserver.onChange(oc.mSelfNotify);
-
......
-
} catch (RemoteException ex) {
-
......
-
}
-
}
-
......
-
} finally {
-
......
-
}
-
}
-
-
......
-
}
-
public final class ContentService extends IContentService.Stub {
-
......
-
-
public static final class ObserverNode {
-
......
-
-
private void collectMyObserversLocked(boolean leaf, IContentObserver observer,
-
boolean selfNotify, ArrayList<ObserverCall> calls) {
-
int N = mObservers.size();
-
IBinder observerBinder = observer == null ? null : observer.asBinder();
-
for (int i = 0; i < N; i++) {
-
ObserverEntry entry = mObservers.get(i);
-
-
// Don't notify the observer if it sent the notification and isn't interesed
-
// in self notifications
-
if (entry.observer.asBinder() == observerBinder && !selfNotify) {
-
continue;
-
}
-
-
// Make sure the observer is interested in the notification
-
if (leaf || (!leaf && entry.notifyForDescendents)) {
-
calls.add(new ObserverCall(this, entry.observer, selfNotify));
-
}
-
}
-
}
-
-
public void collectObserversLocked(Uri uri, int index, IContentObserver observer,
-
boolean selfNotify, ArrayList<ObserverCall> calls) {
-
String segment = null;
-
int segmentCount = countUriSegments(uri);
-
if (index >= segmentCount) {
-
// This is the leaf node, notify all observers
-
collectMyObserversLocked(true, observer, selfNotify, calls);
-
} else if (index < segmentCount){
-
segment = getUriSegment(uri, index);
-
// Notify any observers at this level who are interested in descendents
-
collectMyObserversLocked(false, observer, selfNotify, calls);
-
}
-
-
int N = mChildren.size();
-
for (int i = 0; i < N; i++) {
-
ObserverNode node = mChildren.get(i);
-
if (segment == null || node.mName.equals(segment)) {
-
// We found the child,
-
node.collectObserversLocked(uri, index + 1, observer, selfNotify, calls);
-
if (segment != null) {
-
break;
-
}
-
}
-
}
-
}
-
}
-
}
-
segment = getUriSegment("content://shy.luo.providers.articles/item/n",0);
-
// Notify any observers at this level who are interested in descendents
-
collectMyObserversLocked(false, observer, selfNotify, calls);
-
segment = getUriSegment("content://shy.luo.providers.articles/item/n",1);
-
// Notify any observers at this level who are interested in descendents
-
collectMyObserversLocked(false, observer, selfNotify, calls);
-
segment = getUriSegment("content://shy.luo.providers.articles/item/n",2);
-
// Notify any observers at this level who are interested in descendents
-
collectMyObserversLocked(false, observer, selfNotify, calls);
-
for (int i=0; i<numCalls; i++) {
-
ObserverCall oc = calls.get(i);
-
try {
-
oc.mObserver.onChange(oc.mSelfNotify);
-
......
-
} catch (RemoteException ex) {
-
......
-
}
-
}
