私もこの行動を観察しました。
addAccountExplicit() が古いアカウントのシステム全体のアカウント再同期をトリガーすることは正しいです。
明確化
ただし、addPeriodic 同期またはリクエスト同期が「即時」同期であるという Zapek の見解は、まったく正しくありません。どちらもただ並んでいます。さらに、addPeriodicSync() には次のことが当てはまります。
これらの定期的な同期は、「syncAutomatically」と「masterSyncAutomatically」の設定を尊重します。これらの同期は指定された頻度でスケジュールされますが、同期操作キューで他の同期が先行している場合、実際に開始されるまでに時間がかかる場合があります。これは、実際の開始時間がずれる可能性があることを意味します。(ドキュメンテーション)
あなたの問題に関連して
あなたが経験することは、同期アダプターの実行に関するトレーニングで説明されています。
メソッド addPeriodicSync() は setSyncAutomatically() を無効にしないため、比較的短期間に複数の同期が実行される場合があります。また、addPeriodicSync() の呼び出しでは、少数の同期アダプター制御フラグのみが許可されます。許可されていないフラグについては、addPeriodicSync() の参照ドキュメントで説明されています。
Android トレーニング同期アダプター
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' (w. 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);
}