9

私の同期アダプターは、1 つのことを除いて、うまく機能します。ユーザーがアプリケーションをインストールした後、私のアプリは 2 回同期します。後で、「設定」で手動で同期すると、期待どおりに一度だけ同期されます。これが発生するのは、アプリの最初の実行だけです。

まだ作成されていない場合はアカウントを作成し、syncadapter を設定する「onCreate」のコードを次に示します。私が間違っていることについてのアイデアはありますか?

    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」ステートメントに従って定期的に同期することです。

4

3 に答える 3

4

私もこの行動を観察しました。

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);
}
于 2014-01-14T10:14:42.093 に答える
2

addPeriodicSync() とは別に同期を要求していますか?

最初にアカウントを追加すると、自動的に同期されます。そのため、余分な同期要求があると、二重同期の原因になります。

それでも問題が解決しない場合は、いつでも設定に最後の同期の時刻を保存し、同期のたびにそれをチェックして、同期の頻度を必要に応じて制限することができます。

それが役立つことを願っています!

于 2012-08-28T18:46:24.993 に答える
1

addAccountExplicitely()は、同期可能な状態が不明なすべてのアカウント (新しく追加された SyncAdapter を含む)の同期を引き起こします。

問題は、SyncAdapter と構成されたアカウントがインストールされている他のアプリの数によっては、実行に数秒から数分かかる場合があることです。

addPeriodicSync() (または requestSync()) はすぐに同期を実行します。これは、ユーザーがアプリの起動時にできるだけ早くデータを確認する必要がある場合に適しています。

クライアントとサーバーの間でデータが変更されていない場合に同期が迅速に最適化されるようにする以外に、できることはあまりありません。

于 2013-03-26T09:58:35.383 に答える