考虑到android的SyncAdapter的无限循环,有很多问题:[1] [2] [3],但没有描述我遇到的问题。
我将同步设置为:
ContentResolver.setIsSyncable(account, AppConstants.AUTHORITY, 1);
ContentResolver.setSyncAutomatically(account, AppConstants.AUTHORITY, true);
ContentResolver.addPeriodicSync(account, AppConstants.AUTHORITY, Bundle.EMPTY, 60);
我的同步适配器支持上传(android:supportsUploading="true"
),这意味着我的ContentProvider
我必须检查数据更改是否来自我的SyncAdapter
,如果是,那么我在不请求同步到网络的情况下通知更改。
boolean syncToNetwork = false;
getContext().getContentResolver().notifyChange(uri, null, syncToNetwork);
我的同步适配器仍然以恒定循环运行,还有什么原因可以触发另一个同步?
答案 0 :(得分:0)
在每次同步中,我向服务器请求数据。对于每个请求,我都会从自定义Account Authenticator获取访问令牌。我决定保存Oauth2刷新令牌,而不是在我的帐户中保存密码,然后可以使用它来刷新访问令牌。使用每个刷新的访问令牌,服务器还会发送一个新的刷新令牌,然后我将其更新到我的帐户:
accountManager.setPassword(account, refreshToken);
那个就是问题所在。通过AOSP代码,我在SyncManager中发现了以下BroadcastReceiver
:
private BroadcastReceiver mAccountsUpdatedReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
updateRunningAccounts();
// Kick off sync for everyone, since this was a radical account change
scheduleSync(null, UserHandle.USER_ALL, null, null, 0 /* no delay */, false);
}
};
这样做,在每个帐户上更改(添加,删除,设置密码)广播发送以触发所有 SyncAdapter
的同步,而不仅仅是您自己的!
老实说,我不知道是什么原因,但我可以看出它是可以利用的 - 我让我的手机(我的应用卡无限循环)跑了一夜,早上电池耗尽,还有我的FUP - 只有谷歌的Docs,幻灯片和表格应用程序每个消耗143MB。