android 同步框架分析

调起同步有四种方式

1 ContentService.notifyChange()

2 requestSync

3 周期

4其他(如账号登陆,网络变化内存低变化等可能出发(一般都是之前发起的任务,没有网络或者内存低,没能执行))


对应的同步客户端设置:

android:accountType="com.letv"  //账号类型

android:contentAuthority="com.provider.Wifi" //authority

android:allowParallelSyncs="false"  //是否可以并行同步(目前最多两个任务并行)

android:supportsUploading="false" //是否支持notifyChange方式发起同步

android:isAlwaysSyncable="true" //是否一开始就是可同步的,如果不是要首先初始化后才能同步

android:userVisible="true"/> //用户是否可见,也就是在setting账号下面是否课件


对于上述1,2两种引起同步的方式,是客户端主动调用,都会走到

public void scheduleSync(Account requestedAccount, intuserId, intreason,

String requestedAuthority,Bundle extras, longbeforeRuntimeMillis,

longruntimeMillis, booleanonlyThoseWithUnkownSyncableState) {String requestedAuthority,Bundle extras, longbeforeRuntimeMillis,longruntimeMillis, booleanonlyThoseWithUnkownSyncableState) {

方法,这个方法的作用就是将同步任务添加到任务队列中,还有准备任务的一些参数和过滤一些无效请求,我们来看看任务是什么样子的

SyncOperation(account.account,account.userId,reason,source,

authority,extras,runtimeMillis,beforeRuntimeMillis,

backoffTime,delayUntil,allowParallelSyncs)

这个就是一个同步任务,添加到SyncQueue
中,其中构造函数的众多参数就是scheduleSync 需要准备的,

详细分析scheduleSync
函数


1过滤无效的账号

2过滤无效的authority

3 过滤无效的请求


这个过程中如果有需要初始化的authority会添加这样任务到队列中


任务添加到队列后(如果队列的内容发生变化,添加多队列的时候会和队列中的元素进行比较,看是否有比较添加该任务到队列)

发送MESSAGE_CHECK_ALARMS
异步消息

切换战场到handler中,消费者

private longmaybeStartNextSyncH() {

1 没有网络 存储控件低 设备休眠mRunningAccounts为null的时候直接返回

2 遍历队列,又检查一遍无效的请求,移除队列,idel的provider则增加回避时间

3 这里就要和正在运行的任务做一些比较,看看是取消正在运行的执行新的,还是其他策略如下

候选任务和一下几种任务比较

longRunning的:类型相同且运行时间超过五分钟的

oldestNonExpeditedRegular:不是加速的且运行时间最久的

conflict:冲突的

对于上述三种情况在某种情况需要重新调度,重新添加到调度队列

如果冲突的不为null

1 如果候选任务(肯定会被调度),是初始化任务,且正在执行的不是初始化任务,并且运行的初始化任务不超过上线,则设置 冲突的任务重新调度


2 如果候选任务是加速的,冲突任务不是加速的,并且两个任务类型一样,则设置冲突任务重新调度


3 如果候选任务是加速的,运行最久的任务不是加速的,,并且候选任务不是初始化的,则重新调度运行醉酒的

4 如果运行时间最长的任务不是 和候选者为同一类型 则重新调度运行时间超过五分钟的(一个)

然后bindservice, OnServiceConnect的时候调起同步


出现软错误的时候设置回退时间 硬错误或者同步成功的时候清除回退时间

关于回退时间的设置在

private voidincreaseBackoffSetting(SyncOperation op) {

函数中,我们来看看逻辑

第一次失败的时候回避时间为0,设置延迟时间为30-33秒之间的一个随机数,回避时间= 当前时间+延迟时间

以后随着软错误次数增加,回避延迟*2,最多不超过一个小时,


那么回避时间是啥呢? 是在添加任务到队列的时候会计算effectiveRunTime,如过这个时间-flexTime大于now的话,则该同步任务不会被执行,这个逻辑在longmaybeStartNextSyncH()函数中执行


就这样吧 然后解释下出现的几个时间

首先介绍

AuthorityInfo 下的三个时间:这个对应与一个同步项

backoffTime:回避时间(没有特殊设置,下次可以同步的时间)

backoffDelay:回避时间间隔,随错误次数翻倍,不超过1小时

delayUntil:用户设置 通过SyncResult返回


SyncOperation中的时间:

latestRunTime // 用于处理冲突,用户调用时候指定,一般是当前时间,或者notifyChange方式是30s

backoff //同AuthorityInfo.backoffTime

delayUntil 同AuthorityInfo.delayUntil

effectiveRunTime: 可以运行的时间 取值:max(max(latestRunTime,delayUntil),delayUntil)

flexTime 宽松时间effectiveRunTime-flexTime>now则不可以运行


所以本地数据库变化是三十秒可以运行



   

你可能感兴趣的:(android 同步框架分析)