8.2.3 ContentResolver的notifyChange分析

数据更新的通知由ContentResolver的notifyChange函数触发。看MediaProvider的update函数的代码如下:

[—>MediaProvider. java:update]


public int update(Uri uri, ContentValues initialValues, String userWhere,

String[]whereArgs){

int count;

int match=URI_MATCHER.match(uri);

DatabaseHelper database=getDatabaseForUri(uri);

//找到对应的数据库对象

SQLiteDatabase db=database.getWritableDatabase();

……

synchronized(sGetTableAndWhereParam){

getTableAndWhere(uri, match, userWhere, sGetTableAndWhereParam);

switch(match){

……

case VIDEO_MEDIA:

case VIDEO_MEDIA_ID:{

ContentValues values=new ContentValues(initialValues);

values.remove(ImageColumns.BUCKET_ID);

values.remove(ImageColumns.BUCKET_DISPLAY_NAME);

……//调用SQLiteDatabase的update函数更新数据库

count=db.update(sGetTableAndWhereParam.table, values,

sGetTableAndWhereParam.where, whereArgs);

……

}……//其他处理

}//switch语句结束

}……//synchronized处理结束

if(count>0&&!db.inTransaction())//调用notifyChange触发通知

getContext().getContentResolver().notifyChange(uri, null);

return count;

}


由以上代码可知,MediaProvider update函数更新完数据库后,将通过notfiyChange函数来通知观察者。notfiyChange函数的代码如下:

[—>ContentResolver. java:notifyChange]


public void notifyChange(Uri uri, ContentObserver observer){

//在一般情况下,observer参数为null。调用另一个notifyChange函数,直接来看它

notifyChange(uri, observer, true);

}

public void notifyChange(Uri uri, ContentObserver observer,

boolean syncToNetwork){

//第三个参数syncToNetwork用于控制是否需要发起一次数据同步请求

try{

//调用ContentService的notifyChange函数

getContentService().notifyChange(

uri, observer==null?null:observer.getContentObserver(),

observer!=null&&observer.deliverSelfNotifications(),

syncToNetwork);

}……

}


由以上代码可知,ContentService的notifyChange函数将被调用,其代码如下:

[—>ContentSerivce:notifyChange]


public void notifyChange(Uri uri, IContentObserver observer,

boolean observerWantsSelfNotifications, boolean syncToNetwork){

long identityToken=clearCallingIdentity();

try{

ArrayList<ObserverCall>calls=new ArrayList<ObserverCall>();

//从根节点开始搜索需要通知的观察者,结果保存在calls数组中

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{

/*

调用客户端IContentObserver Bn端,即ContentObserver

内部类Transport的onChange函数。最后再由Transport调用

客户端提供的ContentObserver子类的onChange函数

*/

oc.mObserver.onChange(oc.mSelfNotify);

}……//异常处理

}

if(syncToNetwork){

SyncManager syncManager=getSyncManager();

if(syncManager!=null){

//发起一次同步请求,相关内容留待8.4节分析

syncManager.scheduleLocalSync(null,

uri.getAuthority());

}

}

}finally{

restoreCallingIdentity(identityToken);

}

}