您的位置:首页 > 编程语言

基于Andoird 4.2.2的同步框架源代码学习——同步提供端

2013-07-01 11:14 453 查看

Android同步框架

同步(synchronization)允许用户将远程数据下载到新的设备上,同时将设备上的帐户数据上传到远端。同步还保证用户能够看到最新的数据。
开发者自然可以通过自己的方式来设计实现同步机制。但是Android系统还是提供了一个可插拔的同步框架。这个框架自动化的执行以下任务:

检查网络可用性
根据用户设定的选项规划、执行同步
重启已经停止的同步

开发者需要向这个框架提供自己定义的同步适配器(Sync adapter)插件。一个sync adapter唯一的与某个servive/content provider相关联。但是后者反过来可以对应多个sync adapter。

SyncAdapter

首先,Android framework尽可能的封装了数据同步相关的共性操作,而将针对特定服务的同步逻辑的具体实现留给了应用程序。这一点具体体现在Android framework提供的
AbstractThreadedSyncAdapter抽象类上。对照官方文档中的描述,在应用开发中提供一个自定义的sync adapter,只需要完成下面的几个步骤:

扩展AbstractThreadedSyncAdapter抽象类,实现它的onPerformSync()抽象方法
在res/xml下创建一个XML文件来描述这个sync adapter
在应用中创建一个service,使之处理名为“android.content.SyncAdapter”的动作

详细步骤可见AbstractThreadedSyncAdapter类的参考文档。
这里主要分析一下AbstractThreadedSyncAdapter类本身,也即是sync adapter的共性部分。
看看参与sync adapter调用的类簇:



下面是启动一次同步的序列图:



简要描述一下:

ISyncAdapter

首先,sync adapter的行为通过ISyncAdapter接口来描述:

/**
* Interface used to control the sync activity on a SyncAdapter
* @hide
*/
oneway interface ISyncAdapter {
/**
* Initiate a sync for this account. SyncAdapter-specific parameters may
* be specified in extras, which is guaranteed to not be null.
*
* @param syncContext the ISyncContext used to indicate the progress of the sync. When
*   the sync is finished (successfully or not) ISyncContext.onFinished() must be called.
* @param authority the authority that should be synced
* @param account the account that should be synced
* @param extras SyncAdapter-specific parameters
*/
void startSync(ISyncContext syncContext, String authority,
in Account account, in Bundle extras);

/**
* Cancel the most recently initiated sync. Due to race conditions, this may arrive
* after the ISyncContext.onFinished() for that sync was called.
* @param syncContext the ISyncContext that was passed to {@link #startSync}
*/
void cancelSync(ISyncContext syncContext);

/**
* Initialize the SyncAdapter for this account and authority.
*
* @param account the account that should be synced
* @param authority the authority that should be synced
*/
void initialize(in Account account, String authority);
}


AbstractThreadedSyncAdapter类中提供一个ISyncAdapter接口的本地服务:

private class ISyncAdapterImpl extends ISyncAdapter.Stub {
public void startSync(ISyncContext syncContext, String authority, Account account,
Bundle extras) {
...
}

public void cancelSync(ISyncContext syncContext) {
...
}

public void initialize(Account account, String authority) throws RemoteException {
...
}
}


并且定义了向外部提供IBinder实例的方法:

/**
* @return a reference to the IBinder of the SyncAdapter service.
*/
public final IBinder getSyncAdapterBinder() {
return mISyncAdapterImpl.asBinder();
}


ISyncAdapter.startSync()

public void startSync(ISyncContext syncContext, String authority, Account account,
Bundle extras) {
...
synchronized (mSyncThreadLock) {
if (!mSyncThreads.containsKey(threadsKey)) {
...
SyncThread syncThread = new SyncThread(
"SyncAdapterThread-" + mNumSyncStarts.incrementAndGet(),
syncContextClient, authority, account, extras);
mSyncThreads.put(threadsKey, syncThread);
syncThread.start();
...
}
...
}
...
}


其实现方式是通过启动一个独立的线程来发起同步。

SyncThread

private class SyncThread extends Thread {
private final SyncContext mSyncContext;
private final String mAuthority;
private final Account mAccount;
private final Bundle mExtras;
private final Account mThreadsKey;
...

@Override
public void run() {
...
try {
...
provider = mContext.getContentResolver().acquireContentProviderClient(mAuthority);
if (provider != null) {
AbstractThreadedSyncAdapter.this.onPerformSync(mAccount, mExtras,
mAuthority, provider, syncResult);
} else {
syncResult.databaseError = true;
}
}
...
}
...
}


这个独立线程的核心就是调用AbstractThreadedSyncAdapter.onPerformSync()方法来执行同步相关的业务逻辑。

这样,总而言之,外界通过从系统中查找得到特定的Sync adapter service,然后通过绑定到这个service来获取ISyncAdapter服务的代理对象。然后调用代理对象来启动/终止同步操作。代理对象与提供同步实现的应用程序进程进行IPC来发起真正的同步过程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐