我的syncadapter运作良好,除了一件事。用户安装应用程序后,我的应用程序同步了两次。以后,如果我在“设置”中手动同步它,则它仅按预期同步一次。这只是该应用程序的第一次运行。
这是我的“onCreate”中的代码,用于创建帐户(如果尚未创建)并设置syncadapter。关于我在做什么错的任何想法吗?
if (accountManager.addAccountExplicitly(appAccount, null, null)) {
ContentResolver.setIsSyncable(appAccount, PROVIDER, 1);
ContentResolver.setSyncAutomatically(appAccount, PROVIDER, true);
Bundle extras = new Bundle();
extras.putBoolean("dummy stuff", true);
ContentResolver.addPeriodicSync(appAccount, PROVIDER, extras, 43200);
}
我期望的行为是,应用程序在安装后立即同步一次,然后根据“addPeriodicSync”语句定期进行同步。
最佳答案
我也观察到了这种行为。
正确的是,addAccountExplicit()将触发旧帐户在系统范围内的帐户重新同步。
澄清
但是,Zapek关于addPeriodic同步或请求同步为“立即”同步的观察并不完全正确。两者都只是排队。此外,以下内容适用于addPeriodicSync():
与您的问题有关
有关运行同步适配器的培训中介绍了您所体验的内容:
Google自己的解决方案看起来像您的解决方案,频率更低(60 * 60 = 3600):
if (accountManager.addAccountExplicitly(account, null, null)) {
// Inform the system that this account supports sync
ContentResolver.setIsSyncable(account, CONTENT_AUTHORITY, 1);
// Inform the system that this account is eligible for auto sync when the network is up
ContentResolver.setSyncAutomatically(account, CONTENT_AUTHORITY, true);
// Recommend a schedule for automatic synchronization. The system may modify this based
// on other scheduled syncs and network utilization.
ContentResolver.addPeriodicSync(
account, CONTENT_AUTHORITY, new Bundle(),SYNC_FREQUENCY);
newAccount = true;
}
主张
我建议在onPerformSync()中使用SyncStats实际上将有关您的初始同步的一些信息返回给系统,以便可以更高效地进行计划。
syncResult.stats.numEntries++; // For every dataset
如果已经安排了其他任务,这可能无济于事-正在调查
另外,可以设置一个标志“isInitialOnPerformSync”(带有sharedPreferences),以备份其他任务。
syncResult.delayUntil = <time>;
我个人并不真正喜欢在初始同步后创建固定的不同步时间范围。
进一步考虑-立即立即同步
如说明中所述,同步不会立即以您的设置运行。有一个解决方案,可以让您立即同步。这不会影响同步设置,也不会导致它们退避,这就是为什么它不能解决您的问题,但是其结果是您的用户将不必等待同步开始。如果您使用此设置,则很重要以这种方式显示应用程序中的主要内容。
代码:
在常规应用程序进程中为isInitialSync设置一个标志(例如,将其保存在defaultSharedPreferences中)。您甚至可以使用初始完成安装或登录后(如果需要身份验证),可以按以下方式调用立即同步。
/**
* Start an asynchronous sync operation immediately. </br>
*
* @param account
*/
public static void requestSyncImmediately(Account account) {
// Disable sync backoff and ignore sync preferences. In other words...perform sync NOW!
Bundle settingsBundle = new Bundle();
settingsBundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
settingsBundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
// Request sync with settings
ContentResolver.requestSync(account, SyncConstants.CONTENT_AUTHORITY, settingsBundle);
}
关于android - Syncadapter onPerformSync首次被调用两次,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12044152/