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. wget命令2(转载)

    wget是一个从网络上自动下载文件的自由工具.它支持HTTP,HTTPS和FTP协议,可以使用HTTP代理. 所谓的自动下载是指,wget可以在用户退出系统的之后在后台执行.这意味这你可以登录系统,启 ...

  2. Ffmpeg和SDL如何同步视频(转)

    ong> PTS和DTS 幸运的是,音频和视频流都有一些关于以多快速度和什么时间来播放它们的信息在里面.音频流有采样,视频流有每秒的帧率.然而,如果我们只是简单的通过数帧和乘以帧率的方式来同步视 ...

  3. spring入门:beans.xml不提示、别名、创建对象的三种方式

    spring的版本是2.5 一.beans.xml文件不提示 Location:spring-framework-2.5.6.SEC01\dist\resources\spring-beans-2.5 ...

  4. JS局部打印两种方法

    所有浏览器都可以 <html> <head title=""> <title>测试打印</title> <style medi ...

  5. canvas、image src、data url、blob file conversion

    //canvas.toDataURL('image/jpeg'), and convert to blob,blob is a File Object. but UC don't support fu ...

  6. 由于jsp include 很多文件后导致java类大小超过65535 bytes 的解决方法(转载)

    昨天,我遇到了一個讓我很頭疼的問題. 我做了一個共通的jsp,單只測它是ok的,可是,放在別的jsp中include它,就會報錯如標題所示:The code of method _jspService ...

  7. ios app相互调用

    被调用app配置 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NS ...

  8. 【IOS学习基础】文件相关

    一.沙盒(SandBox) 1.沙盒机制 1> 每个应用都有属于自己的存储空间,即沙盒. 2> 应用只能访问自己的沙盒,不可访问其他区域. 3> 如果应用需要进行文件操作,则必须将文 ...

  9. Lowest Common Ancestor of a Binary Search Tree、Lowest Common Ancestor of a Binary Search Tree

    1.Lowest Common Ancestor of a Binary Search Tree Total Accepted: 42225 Total Submissions: 111243 Dif ...

  10. 龙芯3A上V8的编译与测试

    使用平台: loongson3a+debian6.0.3+linux2.6.36.3+gcc4.6.3 一: V8的下载 这里V8是从其官网上使用git下载的: (1)如果没有git和git-svn需 ...