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来发起真正的同步过程。





基于Andoird 4.2.2的同步框架源代码学习——同步提供端的更多相关文章

  1. 基于Andoird 4.2.2的同步框架源代码学习——同步发起端

    关键组件: ContentResolver ContentService SyncManager SyncManager.ActiveSyncContext SyncManager.SyncOpera ...

  2. 基于Andoird 4.2.2的Account Manager源代码分析学习:AccountManagerService系统服务的添加

    从启动说起 Android系统加载时,首先启动init进程,该进程会启动Zygote进程.Zygote进程执行/system/bin/app_process程序.app_process程序在执行中,通 ...

  3. 基于Andoird 4.2.2的Account Manager源代码分析学习:创建选定类型的系统帐号

    AccountManager.addAccount() public AccountManagerFuture<Bundle> addAccount(final String accoun ...

  4. 【原创】NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示

    前言 NIO框架的流行,使得开发大并发.高性能的互联网服务端成为可能.这其中最流行的无非就是MINA和Netty了,MINA目前的主要版本是MINA2.而Netty的主要版本是Netty3和Netty ...

  5. 【原创】NIO框架入门(一):服务端基于Netty4的UDP双向通信Demo演示

    申明:本文由作者基于日常实践整理,希望对初次接触MINA.Netty的人有所启发.如需与作者交流,见文签名,互相学习. 学习交流 更多学习资料:点此进入 推荐 移动端即时通讯交流: 215891622 ...

  6. 基于TILE-GX实现快速数据包处理框架-netlib实现分析【转】

    最近在研究suricata源码,在匹配模式的时候,有tilegx mpipe mode,转载下文,了解一下. 原文地址:http://blog.csdn.net/lhl_blog/article/de ...

  7. 基于SOA分布式架构的dubbo框架基础学习篇

    以需求用例为基,抽象接口,Case&Coding两条线并行,服务(M)&消费(VC)分离,单元.接口.功能.集成四层质量管理,自动化集成.测试.交付全程支持. 3个大阶段(需求分析阶段 ...

  8. 分布式消息总线,基于.NET Socket Tcp的发布-订阅框架之离线支持,附代码下载

    一.分布式消息总线以及基于Socket的实现 在前面的分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载一文之中给大家分享和介绍了一个极其简单也非常容易上的基于.N ...

  9. 分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载

    一.分布式消息总线 在很多MIS项目之中都有这样的需求,需要一个及时.高效的的通知机制,即比如当使用者A完成了任务X,就需要立即告知使用者B任务X已经完成,在通常的情况下,开发人中都是在使用者B所使用 ...

随机推荐

  1. House Robber 解答

    Question You are a professional robber planning to rob houses along a street. Each house has a certa ...

  2. UVA 10152-ShellSort(映射+栈)

    题意: 给出一堆乌龟名字,乌龟能从本身位置爬到顶端. 要求求出从原本的顺序到目标顺序的最小操作.输出每次操作移到顶端的乌龟的名字. 解析:名字用映射对应编号,把目标状态的乌龟从上到下的编号按1到N编好 ...

  3. tangible T4 Editor 2.2.3 plus modeling tools for VS 2012 扩展名

    tangible T4 Editor 2.2.3 plus modeling tools for VS 2012 扩展名 tangible T4 Editor 2.2.3 plus modeling ...

  4. N种方法妙讲LIS算法

    LIS算法经典汇总 假设存在一个序列d[1..9] = 2 1 5 3 6 4 8 9 7,可以看出来它的LIS长度为5.下面一步一步试着找出它.我们定义一个序列B,然后令 i = 1 to 9 逐个 ...

  5. Lazy方式单列模式,一种线程安全模式的新选择

      public class WeProxyClient {         private static readonly Lazy<WeProxyClient> list = new ...

  6. 教训:TOJ[4081] God Le wants to know the directory

    以前的字符串题本来就弱..2年不写就更弱了.嗯.留作教训 God Le is the most talented ACMer in the TJU-ACM team. When he wants to ...

  7. 「前端开发者」如何把握住「微信小程序」这波红利?

    由于前两周一直在老家处理重要事情,虽然朋友圈被「微信小程序」刷爆了,但并没有时间深入了解. 昨天回广州之后,第一件事情就是把「微信小程序」相关的文章.开发文档.设计规范全部看了一遍,基本上明白了「微信 ...

  8. 生成html文件

    第一步:建立一个MbPage.html页面 第二步:后台生成 public void ProcessRequest(HttpContext context)        {            c ...

  9. vs2012 设计器 视图异常

    WPF 开发/(其他xaml app 的开发) 的时候 设计视图功能非常方便  不过有时候经常遇到 设计器加载失败的情况,原因很多  很多时候是代码问题导致,设计器无法展现视图,也有sliverlig ...

  10. ASP.NET MVC 常用内置验证特性

    1.[Required] : 必须输入 [Required(ErrorMessage = "请输入用户名")] 2.[StringLength] : 限制字符串长度 [String ...