我的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/

10-13 05:30