上一篇博文我介绍了账号与同步的同步实现过程,其中提供了一个工系统进程调用的服务,那么这个服务到底是怎么被启动和使用的呢?这篇博文我就大体梳理一下启动过程。
其实作为一个一般开发人员,我们只要知道要想知道被监听的ContentProvider有变动,首先那个ContentProvider必须使用ContentResolver.notifyChange(android.net.Uri,
android.database.ContentObserver, boolean)这个方法来通知我们。我们知道这个方法会通知监听这个ContentProvider的ContentObserver数据有变化,但是ContentObserver需要在一个运行这个的进程中注册,如果这个进程死掉了ContentObserver也需要取消注册监听,这样就没法监听了。不过值得注意的是,这个notifyChange方法还有另外一个作用,就是配合实现android的同步框架,通知SyncManager启动相应账号的同步。
ContentResolver.java
首先我们来看看ContentResolver的notifyChange源码,如下:
public void notifyChange(Uri uri, ContentObserver observer) {
notifyChange(uri, observer, true /* sync to network */);
}
public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
notifyChange(uri, observer, syncToNetwork, UserHandle.getCallingUserId());
}
public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork,
int userHandle) {
try {
getContentService().notifyChange(
uri, observer == null ? null : observer.getContentObserver(),
observer != null && observer.deliverSelfNotifications(), syncToNetwork,
userHandle);
} catch (RemoteException e) {
}
}
上面重载的三个notifyChange方法,最终调用的都是ContentService中的notifyChange方法,getContentService()方法如下:
public static IContentService getContentService() {
if (sContentService != null) {
return sContentService;
}
IBinder b = ServiceManager.getService(CONTENT_SERVICE_NAME);
if (false) Log.v("ContentService", "default service binder = " + b);
sContentService = IContentService.Stub.asInterface(b);
if (false) Log.v("ContentService", "default service = " + sContentService);
return sContentService;
}
ContentService.java
ContentService是对存根类IContentService.Stub的实现,它提供一系列数据同步及数据访问等相关的操作,源码如下:
public final class ContentService extends IContentService.Stub
此类中的两个重载的notifyChange方法如下:
public void notifyChange(Uri uri, IContentObserver observer,
boolean observerWantsSelfNotifications, boolean syncToNetwork) {
notifyChange(uri, observer, observerWantsSelfNotifications, syncToNetwork,
UserHandle.getCallingUserId());
}
@Override
public void notifyChange(Uri uri, IContentObserver observer,
boolean observerWantsSelfNotifications, boolean syncToNetwork,
int userHandle) {
...
最重要的一句,就是启动ContentObserver的onChange方法
oc.mObserver.onChange(oc.mSelfChange, uri);
...
最重要的另一句,就是启动同步
if (syncToNetwork) {
SyncManager syncManager = getSyncManager();
if (syncManager != null) {
syncManager.scheduleLocalSync(null /* all accounts */, callingUserHandle, uid,
uri.getAuthority());
}
}
} finally {
restoreCallingIdentity(identityToken);
}
}
//获取SyncManager 的方法
private SyncManager getSyncManager() {
if (SystemProperties.getBoolean("config.disable_network", false)) {
return null;
}
synchronized(mSyncManagerLock) {
try {
// Try to create the SyncMana